web-dev-qa-db-fra.com

Afficher le parent de niveau supérieur avec le menu du sous-menu

J'ai utilisé le menu ci-dessous pour afficher des sous-menus dynamiques avec un grand effet dans le passé.

Il affiche les éléments de menu de niveau 2 ou inférieur SI la page en cours est un parent, un frère ou un descendant de la page.

Par exemple, si la hiérarchie du menu est:

  • une
  • b
    • 1
      • je
      • ii

Il indiquera 1, i et ii si aux pages B, 1, i ou ii. Ce que je veux faire, c'est ajouter l'élément parent (B dans l'exemple), afin que le parent de niveau supérieur apparaisse également.

J'ai lu des articles sur les marcheurs, j'ai essayé de comprendre ce code, mais je suis toujours bloqué sur le point de savoir par où commencer.

// 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";
        }
    }
}
3
mrwweb

Vous pouvez essayer d'ignorer la condition if- suivante dans la méthode start_el() de votre classe child_menu_walker:

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

qui est égal à:

if ($item->menu_item_parent != 0 ) {
    //...
}

puisque vous avez $parent_item_id = 0.

Il semble donc que cette condition filtre votre parent de niveau supérieur .

Vous pouvez également vouloir reconsidérer cette condition:

&& $item->menu_item_parent != $parent_item_id

dans la méthode end_el().

1
birgire