如何以分层的方式显示分类术语

时间:2015-12-22 作者:Mayeenul Islam

阅读Kaiser\'s query and Scribu\'s answer 我现在在一个没有海岸的海洋里。我制定了一个自定义分类法,在这里我想按照术语的层次结构显示术语,如下所示:

Level 0
-- Level 1
--- Level 2
---- Level 3
--- Level 2
---- Level 3
---- Level 3
-- Level 1
--- Level 2
但我使用失败orderby => \'term_group\' 在两者中get_categories()get_terms(). 使用term_group 我得到的是:

Level 0
-- Level 1
-- Level 1
--- Level 2
--- Level 2
--- Level 2
---- Level 3
---- Level 3
---- Level 3
我已经检查了数据,所有的层次结构都是完美的,但在我的代码中,它们在前端没有明显的工作。但当我一个接一个地手工输入术语时,以下代码起作用:

$all_terms = get_categories( array(
                    \'taxonomy\'          => \'my_tax\',
                    \'show_count\'        => true,
                    \'hide_empty\'        => false,
                    \'orderby\'           => \'term_group\',
                ) );
但是,当我使用自动脚本输入/迁移数据时,级别0先输入,然后是级别1,依此类推,相同的代码不起作用。所以我想,orderby实际上是在处理ID(是的,实际上是这样)。

如何以分层的方式显示分类术语?

2 个回复
最合适的回答,由SO网友:Mayeenul Islam 整理而成

我在同事阿夫扎尔先生的帮助下,用简单的PHP解决了这个问题。我现有的查询是:

$all_terms = get_categories( array(
                    \'taxonomy\'          => \'my_tax\',
                    \'show_count\'        => true,
                    \'hide_empty\'        => false,
                    \'orderby\'           => \'term_group\', //bogus :p
                ) );
我将其改为$wpdb 查询以获得更好的控件:

global $wpdb;
$tax_query = $wpdb->get_results("SELECT t.*, tt.* FROM $wpdb->terms AS t
                                        INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
                                        WHERE tt.taxonomy IN (\'my_tax\')
                                        ORDER BY tt.parent, t.name ASC
                                    ", ARRAY_A);
因此,我们现在有了按字母顺序排序的数组,其中包含一些有价值的信息,我需要这些信息来进行进一步的讨论:

  • term_id
  • parent

层次结构数组

我使用this SO thread, 这是一个递归函数:

function create_tax_tree( &$list, $parent ) {
    $taxTree = array();
    foreach( $parent as $ind => $val ) {
        if( isset($list[$val[\'term_id\']]) ) {
            $val[\'children\'] = create_tax_tree( $list, $list[$val[\'term_id\']] );
        }
        $taxTree[] = $val;
    }
    return $taxTree;
}
这个函数将使我成为一个具有精确父子关系的数组。在db查询之后,我现在执行了以下操作:

if (count( $tax_query ) > 0) :

    //Making my tree array
    $taxs = array();
    foreach( $tax_query as $tax ) {
        $taxs[ $tax[\'parent\'] ][] = $tax;
    }
    //that\'s my tree in array or arrays
    $tax_tree = create_tax_tree( $taxs, $taxs[0] );

else :

    _e(\'No term found\', \'textdomain\');

endif;
现在我的树在$tax_tree 变量如果我var_dump($tax_tree), 这是一个数组数组,充满了精确的父子关系。

最终结果

要获得最终结果,我们需要另一个递归函数,这里PHP5提供了nice bunch of classes, 从中学习this SO thread. 我以以下方式使用其中两个:

$tax_iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator( $tax_tree ));

foreach( $tax_iterator as $key => $value ) {
    $depth = get_tax_depth( $term_id, true ); //custom-made function
    if( \'term_id\' === $key )
        $term_id = (int) $value; //having the term_id for further use

    if( \'name\' === $key ) {
        echo \'<p>\';
            $pad = str_repeat(\'---\', $depth * 3); //for visual hierarchy
            echo $pad .\' \'. $value; //the name of the tax term
        echo \'</p>\';
    }
}
输出为:

Level 0
-- Level 1
--- Level 2
---- Level 3
--- Level 2
---- Level 3
---- Level 3
-- Level 1
--- Level 2
:)

SO网友:Pieter Goosen

term_group 似乎从未与alias_of 参数确切的非故意用途是什么,我不能肯定。我宁愿避免使用这两个参数。

关于创建层次结构树的问题,wp_list_categories() 马上就想到了(记住这也适用于自定义分类法)。您可以使用wp_list_categories() 并通过可用的参数操作输出,或者您可以查看walk_category_tree() 哪一个wp_list_categories() 用于构建其树。walk_category_tree() 同时使用Walker_Category class, 所以你可以用它来精确微调你需要的

还可以选择编写自己的递归函数来创建树