对自定义菜单查看器中的顶级项进行计数

时间:2015-11-16 作者:clancimus

我正在创建一个拆分菜单(一半项目位于左侧,徽标位于中间,其余项目位于右侧)。我不太了解Walkers但我发现this code snippet.

在我的客户想要添加子项之前,这对我来说很有效。当前代码正在计算所有菜单项(10),而我希望它只计算顶级项(当前为7)。

如何调整此代码,使其仅统计顶级项目?

class Split_Menu_Walker extends Walker_Nav_Menu {

    var $current_menu = null;
    var $break_point  = null;

    function start_el(&$output, $item, $depth, $args, $id=0) {

        global $wp_query;

        if( !isset( $this->current_menu ) )
            $this->current_menu = wp_get_nav_menu_object( $args->menu );

        if( !isset( $this->break_point ) )
            $this->break_point = ceil( $this->current_menu->count / 2 ) + 1;

        $indent = ( $depth ) ? str_repeat( "\\t", $depth ) : \'\';

        $class_names = $value = \'\';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = \'menu-item-\' . $item->ID;

        $class_names = join( \' \', apply_filters( \'nav_menu_css_class\', array_filter( $classes ), $item, $args ) );
        $class_names = \' class="\' . esc_attr( $class_names ) . \'"\';

        $id = apply_filters( \'nav_menu_item_id\', \'menu-item-\'. $item->ID, $item, $args );
        $id = strlen( $id ) ? \' id="\' . esc_attr( $id ) . \'"\' : \'\';

        if( $this->break_point == $item->menu_order )
            $output .= $indent . \'</li></ul><ul><li\' . $id . $value . $class_names .\'>\';
        else
            $output .= $indent . \'<li\' . $id . $value . $class_names .\'>\';

        $attributes  = ! empty( $item->attr_title ) ? \' title="\'  . esc_attr( $item->attr_title ) .\'"\' : \'\';
        $attributes .= ! empty( $item->target )     ? \' target="\' . esc_attr( $item->target     ) .\'"\' : \'\';
        $attributes .= ! empty( $item->xfn )        ? \' rel="\'    . esc_attr( $item->xfn        ) .\'"\' : \'\';
        $attributes .= ! empty( $item->url )        ? \' href="\'   . esc_attr( $item->url        ) .\'"\' : \'\';

        $item_output = $args->before;
        $item_output .= \'<a\'. $attributes .\'>\';
        $item_output .= $args->link_before . apply_filters( \'the_title\', $item->title, $item->ID ) . $args->link_after;
        $item_output .= \'</a>\';
        $item_output .= $args->after;

        $output .= apply_filters( \'walker_nav_menu_start_el\', $item_output, $item, $depth, $args );
    }
}

1 个回复
最合适的回答,由SO网友:Mateusz Marchel 整理而成

你在说什么

if( !isset( $this->break_point ) )
        $this->break_point = ceil( $this->current_menu->count / 2 ) + 1;
这样无法获得顶级项目计数。相反,你应该自己数。您可以使用wp_get_nav_menu_items(). 每个顶级项都应将menu\\u item\\u parent设置为“0”。

您应该在计算已显示元素的位置创建其他变量。因此,文件顶部应如下所示:

class Split_Menu_Walker extends Walker_Nav_Menu {

    public $break_point = null;
    public $displayed = 0; 

function start_el(&$output, $item, $depth, $args, $id=0) {

    global $wp_query;

    if( !isset( $this->break_point ) ) {
        $menu_elements = wp_get_nav_menu_items( $args->menu );
        $top_level_elements = 0;

        foreach( $menu_elements as $el ) {
            if( $el->menu_item_parent === \'0\' ) {
                $top_level_elements++;
            }
        }
        $this->break_point = ceil( $top_level_elements / 2 ) + 1;
     }   


    $indent = ( $depth ) ? str_repeat( "\\t", $depth ) : \'\';
...
...
...
那么你应该增加$this->displayed++; 每次显示顶级元素时(例如,在start\\u el()函数的末尾):

if( $item->menu_item_parent === \'0\' ) {
    $this->displayed++;
}
最后,而不是

if( $this->break_point == $item->menu_order ) 
您应该使用

if( $this->break_point == $this->displayed )