如何从定制分类中动态填充wp_NAV_MENU?

时间:2011-11-17 作者:djb

我知道有人以不同的形式问过这个问题。但就我在谷歌和SE/WP上的搜索结果来看,它从来没有得到令人满意的回答。

假设我有一个分类法俱乐部和一个自定义的帖子类型person。

在每个taxonomy-club.php 第一页显示该俱乐部的所有成员。

But 我想在菜单中实现类似的效果:

wp_nav_menu
|
|--Everyone
|  \\
|  |- Mr Verlaine
|  |- Mr Lloyd
|  |- Mr Osterberg 
|  |- Mr Williamson    
|
|--Snooker Club
|  \\ 
|  |- Mr Osterberg 
|  |- Mr Williamson
|
|--Golf Club
|  \\
|  |- Mr Verlaine
|  |- Mr Lloyd
如果可能,我希望菜单的当前页面突出显示wp_nav_menu().

我尝试过这个:

add_filter(\'wp_nav_menu_items\',\'add_terms\');

function add_terms($items) {
$items .= \'<li>\' . wp_list_categories( array(
    \'taxonomy\' => \'clubs\', 
    \'title_li\' => \'Clubs\') ) 
     . \'</li>\';
return $items;
}
但是它没有用人名填充子菜单,也没有nav\\u菜单css类的优点。

我必须创建一个更复杂的<li> 通过查询分类法每个术语中的帖子,将其粘贴进去,这就是我的命运?或者扩展内置助行器(它会给我提供wp\\U nav\\U菜单的优势吗?)

或者别的什么。。。

谢谢

1 个回复
最合适的回答,由SO网友:Ján Bočínec 整理而成

我会选择自定义导航菜单漫游器。。。

//define the custom post type and custom taxonomy
define("MENU_CPT", "people");
define("MENU_CT", "club");

//custom function for selecting posts based on a term
function get_posts_by_term($term_id, $post_type=MENU_CPT, $taxonomy=MENU_CT) {
    $args = array(
        \'posts_per_page\' => -1,
        \'post_type\' => $post_type,
        \'tax_query\' => array(
            array(
                \'taxonomy\' => $taxonomy,
                \'field\' => \'id\',
                \'terms\' => $term_id
            )
        )
    );                  
    return get_posts( $args );
}

//custom nav menu walker class
class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {
    /**
     * Display array of elements hierarchically.
     *
     * It is a generic function which does not assume any existing order of
     * elements. max_depth = -1 means flatly display every element. max_depth =
     * 0 means display all levels. max_depth > 0  specifies the number of
     * display levels.
     *
     * @since 2.1.0
     *
     * @param array $elements
     * @param int $max_depth
     * @return string
     */
    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = \'\';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields[\'id\'];
        $parent_field = $this->db_fields[\'parent\'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field ) 
            {
                $top_level_elements[] = $e;
                if ( $e->type==\'taxonomy\' && $e->object == MENU_CT ) {

                    $taxonomy_posts = get_posts_by_term($e->object_id);

                    foreach ( $taxonomy_posts as $tax_post ) {                      
                        $tax_post = wp_setup_nav_menu_item($tax_post);
                        $tax_post->post_type = \'nav_menu_item\';
                        $tax_post->menu_item_parent = $e->$id_field;
                        $tax_post->object = \'custom\';
                        $tax_post->type = \'custom\';
                        $tax_post->ID = $e->$id_field.$tax_post->ID;
                        $children_elements[ $e->$id_field ][] = $tax_post; 
                        $children_elements_classes[] = $tax_post; 
                    }
                }
            }
            else
            {
                $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                {
                    $top_level_elements[] = $e;
                    if ( $e->type==\'taxonomy\' && $e->object == MENU_CT ) {

                        $taxonomy_posts = get_posts_by_term($e->object_id);

                        foreach ( $taxonomy_posts as $tax_post ) {                      
                            $tax_post = wp_setup_nav_menu_item($tax_post);
                            $tax_post->post_type = \'nav_menu_item\';
                            $tax_post->menu_item_parent = $e->$id_field;
                            $tax_post->object = \'custom\';
                            $tax_post->type = \'custom\';
                            $tax_post->ID = $e->$id_field.$tax_post->ID;
                            $children_elements[ $e->$id_field ][] = $tax_post;
                            $children_elements_classes[] = $tax_post; 
                        }
                    }
                }
                else
                {
                    $children_elements[ $e->$parent_field ][] = $e;
                }
            }
        }

        //assing the classes to our dynamically populated posts
        if ( $children_elements_classes )
            _wp_menu_item_classes_by_context($children_elements_classes);

        foreach ( $top_level_elements as $e )
            $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }

         return $output;
    }
}
。。。您现在可以在中使用它wp_nav_menu 功能:

wp_nav_menu( array( \'theme_location\' => \'primary\', \'walker\' => new Custom_Walker_Nav_Menu ) );
当您将定义的分类法中的术语放入菜单时,它将自动由特定分类法术语定义的自定义帖子类型中的帖子(人名)填充。

结束

相关推荐

如何从wp_title中删除“Taxonomy Name:”

生成的wp\\U标题<title> 在我的自定义分类法归档页面中,包含带有冒号的单数分类法名称。我不知道这是从哪里来的(或者它是否是默认的Wordpress行为),我想删除它。例如,在名为“香精”的分类法中术语“香草”的归档页面中<title> 是口味:香草|我的网站名称我想要的标题是香草|我的网站名称标题中的代码。php是这样的:<title><?php wp_title(\'|\', true, \'right\'); ?></title>&