使用子菜单菜单漫游显示顶级父项

时间:2013-10-28 作者:mrwweb

过去,我使用下面的菜单漫游器显示动态子菜单,效果很好。

如果当前页面是页面的父级、同级或子级,则会显示第二级或更低级别的菜单项。

例如,如果菜单层次结构为:

如果在b、1、i或ii页上,它将显示1、i和ii。我要做的是将父项(示例中的B)添加到该项中,以便顶级父项也出现。

我读过walkers的书,试图理解这段代码,但即使从哪里开始,我仍然感到困惑。

// Show only the child pages of a menu
class child_menu_walker extends Walker_Nav_Menu {
    var $found_parents = array();

    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;

        if( $wp_query->is_single && !in_array( get_option(\'page_for_posts\'), $this->found_parents ) ) {
            $this->found_parents[] = get_option(\'page_for_posts\');
        }

        //this only works for second level sub navigations
        $parent_item_id = 0;

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

        $class_names = \'\';
        $classes = empty($item->classes) ? array() : (array) $item->classes;
        $class_names = join(\' \', apply_filters(\'nav_menu_css_class\', array_filter($classes), $item));
        $class_names = \' class="\'.esc_attr($class_names).\'"\';

        #current_page_item
        // Checks if the current element is in the current selection
        if(
            strpos($class_names, \'current-menu-item\') || 
            strpos($class_names, \'current-menu-parent\') || 
            strpos($class_names, \'current-menu-ancestor\') || 
            ( is_array($this->found_parents) && 
                in_array($item->menu_item_parent, $this->found_parents) )
        ) {
            // Keep track of all selected parents
            $this->found_parents[] = $item->ID;
            //check if the item_parent matches the current item_parent
            $item_output = \'\';
            if ($item->menu_item_parent != $parent_item_id ) {
                $output .= $indent.\'<li\'.$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);
        }
    }

    function end_el(&$output, $item, $depth) {
        $parent_item_id = 0;

        $class_names = \'\';
        $classes = empty($item->classes) ? array() : (array) $item->classes;
        $class_names = join(\' \', apply_filters(\'nav_menu_css_class\', array_filter($classes), $item));
        $class_names = \' class="\'.esc_attr($class_names).\'"\';

        if(
            strpos($class_names, \'current-menu-item\') || 
            strpos($class_names, \'current-menu-parent\') || 
            strpos($class_names, \'current-menu-ancestor\') || 
            (is_array($this->found_parents) && 
                in_array($item->menu_item_parent, $this->found_parents))
        ) {
            // Closes only the opened li
            if (is_array($this->found_parents) && in_array($item->ID, $this->found_parents) && $item->menu_item_parent != $parent_item_id) {
                $output .= "</li>\\n";
            }
        }
    }

    function end_lvl(&$output, $depth) {
        $indent = str_repeat("\\t", $depth);
        // If the sub-menu is empty, strip the opening tag, else closes it
        if (substr($output, -22) == "<ul class=\\"sub-menu\\">\\n") {
            $output = substr($output, 0, strlen($output) - 23);
        } else {
            $output .= "$indent</ul>\\n";
        }
    }
}

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

您可以尝试跳过以下内容if-中的条件start_el() 方法child_menu_walker 类别:

if ($item->menu_item_parent != $parent_item_id ) {
    //...
}
等于:

if ($item->menu_item_parent != 0 ) {
    //...
}
既然你有$parent_item_id = 0.

因此,这种情况似乎正在过滤掉您的顶级父级。

您可能还需要重新考虑此条件:

&& $item->menu_item_parent != $parent_item_id
end_el() 方法

结束

相关推荐

错误:MyClass::Start_lvl()的声明应与Walker_Nav_Menu::Start_lvl()的声明兼容

我目前正在WordPress网站上工作,每当我在管理中进入“外观>菜单”页面时,我都会遇到以下错误:错误异常:运行时通知:Walker\\u Nav\\u Menu\\u Edit::start\\u lvl()的声明应与wp admin/includes/Nav Menu中Walker\\u Nav\\u Menu::start\\u lvl()的声明兼容。php第203行这似乎是某种PHP兼容性问题。我正在本地开发机器上运行PHP 5.3.10。解决这个问题的最佳方法是什么?