web-dev-qa-db-fra.com

Navigation simple - Classe d'emballage autour du premier sous-menu

J'essaie d'envelopper le premier sous-menu d'une navigation dans un div séparé. Aucun des enfants ou des sous-niveaux ne devrait recevoir le même traitement.

Je suis vraiment nouveau dans le Nav Walker-thingie et j'ai vraiment du mal à avoir besoin d'aide. ????

C'est la structure que j'essaie de réaliser:

<ul class="menu">
    <li class="menu-item">
        <a href="#">Menu Item</a>
        <!-- wrapper-class around the first sub-menu -->
        <div class="sub-menu__wrapper">
            <ul class="sub-menu">
                <li class="menu-item">
                    <a href="#">Menu Item</a>
                    <!-- NO wrapper-class around following levels -->
                    <ul class="sub-menu">
                        <li>...</li>
                    </ul>
                </li>
            </ul>
        </div>
    </li>
</ul>

Je pensais que ce serait facile à faire avec une simple instruction if qui n'imprime que le sous-menu__wrapper du premier niveau, mais d'une certaine manière, la sortie HTML suivante est mal mélangée.

Voici ma classe Walker:

class sublevel_wrapper extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        if ($depth == 0) {
            $output .= "<div class='sub-menu__wrapper'><ul class='sub-menu'>\n";
        }
        //$output .= "<ul class='sub-menu'>\n";
    }
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        if ($depth == 0) {
            $output .= "</ul></div>\n";
        }
        //$output .= "</ul>\n";
    }
}

Qui imprime la structure suivante:

<ul class="menu">
    <li class="menu-item">
        <a href="#">Menu Item</a>
        <!-- wrapper-class around the first sub-menu -->
        <div class="sub-menu__wrapper">
            <ul class="sub-menu">
                <li class="menu-item">Parent Menu Item</li>
                <!-- the following items are supposed to be nested in the "parent menu item" before -->
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Parent Menu Item</li>
                <!-- again the following items are supposed to be nested in the "parent menu item" before -->
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                <li class="menu-item">Child Menu Item</li>
                ...
            </ul>
        </div>
    </li>
</ul>

Comme vous pouvez le voir dans les commentaires, j'ai essayé de modifier le résultat, si l'instruction if est fausse, mais cela gâche encore plus le résultat ????

Toute aide, critique constructive ou Nudge dans la bonne direction est très appréciée ????

1
Jörg Mayer

Pour être honnête, je ne sais pas vraiment pourquoi ma solution fonctionne, mais ça marche ????

J'ai basé mon extrait sur cette solution et peaufiné la sortie selon mes besoins: Promeneur de navigation personnalisé avec une sortie différente selon la profondeur

class sublevel_wrapper extends Walker_Nav_Menu {
    // add classes to ul sub-menus
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        // depth dependent classes
        $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
        $display_depth = ( $depth + 1); // because it counts the first submenu as 0
        $classes = array(
            'sub-menu',
            'menu-depth-' . $display_depth
        );
        $class_names = implode( ' ', $classes );

        // build html
        if ($display_depth == 1) {
            $output .= "\n" . $indent . '<div class="sub-menu__wrapper"><ul class="' . $class_names . '">' . "\n";
        } else {
            $output .= "\n" . $indent . '<ul class="' . $class_names . '">' . "\n";
        }
    }
}

Comparé à mon premier extrait, il laisse de côté la fonction end_lvl et, pour une raison quelconque, cela a fonctionné. J'ai également aimé la façon dont il ajoute la variable $ display_depth.

1
Jörg Mayer
function sevenMenu(  ) {
$menu_name = 'primary'; // specify custom menu slug
$menu_list ='';
if (($locations = get_nav_menu_locations()) && isset($locations[$menu_name])) {
    $menu = wp_get_nav_menu_object($locations[$menu_name]);
    $menu_items = wp_get_nav_menu_items($menu->term_id);

    foreach( $menu_items as $menu_item ) {
        if( $menu_item->menu_item_parent == 0 ) {

            $parent = $menu_item->ID;

            $menu_array = array();
            foreach( $menu_items as $submenu ) {
                if( $submenu->menu_item_parent == $parent ) {
                    $bool = true;
                    $menu_array[] = '<li><a href="' . $submenu->url . '">' . $submenu->title . '</a></li> ' ."\n";
                }
            }
            if( $bool == true && count( $menu_array ) > 0 ) {
                $menu_list .= '<li role="presentation" class="dropdown">' ."\n";
                $menu_list .= '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">' . $menu_item->title . ' <span class="caret"></span></a>' ."\n";

                $menu_list .= '<ul class="dropdown-menu">' ."\n";
                $menu_list .= implode( "\n", $menu_array );
                $menu_list .= '</ul>' ."\n";

            } else {

                $menu_list .= '<li>' ."\n";
                $menu_list .= '<a href="' . $menu_item->url . '">' . $menu_item->title . '</a>' ."\n";
                $menu_list .= '<li>' ."\n";
            }

        }

        // end <li>

    }

} else {
    $menu_list = '<!-- no menu defined in location "'.$theme_location.'" -->';
}

echo $menu_list;}

Check Out Ce menu de démarrage, vous pouvez l'ajouter à votre function.php, changer votre nom de menu et appeler ce menu dans votre modèle en:

<?php if (function_exists(sevenMenu())) sevenMenu(); ?>
1
Roland Allla