以下のメニューウォーカーを使用して、過去に大きな効果を持つ動的サブメニューを表示しました。
現在のページがそのページの親、兄弟、または子孫である場合は、2番目または下位のメニュー項目が表示されます。
たとえば、メニュー階層が次のようになっているとします。
ページB、1、i、またはiiの場合は、1、i、およびiiが表示されます。最上位の親も表示されるように、親項目(例ではB)をそれに追加します。
私はこのコードを理解しようと、ウォーカーについて読んだことがありますが、それでもどこから始めても動けなくなります。
// 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";
}
}
}
child_menu_walker
クラスのstart_el()
メソッドで、次のif
-条件をスキップすることもできます。
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()
メソッドで。