过去,我使用下面的菜单漫游器显示动态子菜单,效果很好。
如果当前页面是页面的父级、同级或子级,则会显示第二级或更低级别的菜单项。
例如,如果菜单层次结构为:
如果在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";
}
}
}