web-dev-qa-db-fra.com

Changer un nom de classe li dans un programme de menu wordpress personnalisé

Je construis un nav qui a une classe appliquée aux LI principaux et aux LI imbriqués. Exemple:

<ul>
<li class="className">Test</li>
<li class="className">Test
    <ul>
        <li class="ADifferentclassName">test</li>
        <li class="ADifferentclassName">test</li>
    </ul>
</li>
</ul>

J'ai compris comment obtenir des cours sur les UL et tous les LI, mais je peux comprendre comment obtenir une classe différente sur les LI imbriqués.

Voici mon marcheur personnalisé:

Cela change la classe UL du nid

 class My_Walker_Nav_Menu extends Walker_Nav_Menu {
  function start_lvl(&$output, $depth) {
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent<ul class=\"nav-main-sub-list\">\n";
  }

Cela supprime toutes les classes de wordpress superflues et ajoute la classe nav-main-item à tous les li

    public function start_el( &$output, $item, $depth, $args )
    {

        $attributes  = '';

        ! empty ( $item->attr_title )
            // Avoid redundant titles
            and $item->attr_title !== $item->title
            and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"';

        ! empty ( $item->url )
            and $attributes .= ' href="' . esc_attr( $item->url ) .'"';

        $attributes  = trim( $attributes );
        $title       = apply_filters( 'the_title', $item->title, $item->ID );
        $item_output = "$args->before<a $attributes>$args->link_before$title</a>"
                        . "$args->link_after$args->after";

        // Since $output is called by reference we don't need to return anything.


        $output .= $indent . '<li class="nav-main-item">';

        $output .= apply_filters(
            'walker_nav_menu_start_el'
            ,   $item_output
            ,   $item
            ,   $depth
            ,   $args
        );
    }   

}

Je n'arrive pas à comprendre comment changer de classe sur les LI imbriqués. Rien de ce que j'ai fait n'a fonctionné. Des conseils?

1
Steph Gill

Dépannage

L'activation de la constante WP_DEBUG dans wp-config.php a révélé les erreurs suivantes:

- Signatures de fonction

Si Strict Standards est activé, vous verrez une erreur détaillant les signatures de méthode incompatibles. Bien que cela ne soit pas absolument nécessaire, j'aime éliminer autant d'erreurs que possible. Pour corriger cela, les déclarations des méthodes start_el() et start_lvl() de la nouvelle classe Walker_Nav_Menu doivent correspondre à à celles de la classe Walker_Nav_Menu elle-même , de sorte que la nouvelle classe puisse fonctionner comme remplacement instantané de la classe Walker_Nav_Menu sans lancer toutes sortes d'erreurs liées aux paramètres/arguments.

Ce:

class Wpse_145991_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth ) {
        //...
    }

    public function start_el( &$output, $item, $depth, $args ) {
        //...
    }
}

devrait devenir ceci:

class Wpse_145991_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        //...
    }

    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        //...
    }
}

- Notice: Undefined variable: indent

Au bas de la méthode start_el() de la nouvelle classe, vous verrez la ligne

$output .= $indent . '<li class="nav-main-item">';

Mais $indent n'est jamais défini dans la méthode. Les classes Walker ont tendance à définir une variable $indent pour formater un espace-blanc HTML avec un nombre de $depth tab-characters. Ce n'est pas pertinent du point de vue fonctionnel, mais cela peut être corrigé en définissant $indent quelque part avant la ligne susmentionnée:

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

À ce stade, la mise en œuvre publiée dans la question devrait générer un menu sans générer d'erreurs ni d'avertissements.


Spécification de différentes classes pour différentes profondeurs

Théorie

Lorsqu'un Walker_Nav_Menu est walk()ing, les méthodes start_el() et start_lvl() reçoivent un argument $depth qui peut être considéré comme étant représentatif du nombre d'éléments "niveaux", "sous-menus" ou <ul> situés entre l'élément actuel et la racine de données (c'est-à-dire élément <ul> de niveau supérieur.

Walker_Nav_Menu $depth Parameter

La mise en oeuvre

En créant une branche conditionnelle basée sur ce $depth, vous pouvez affecter différentes classes pour différents éléments et niveaux. Par exemple, l’utilisation de switch vous permettrait d’affiner les classes pour chaque élément et chaque niveau:

class Wpse_145991_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat( "\t", $depth );

        // Select a CSS class for this `<ul>` based on $depth
        switch( $depth ) {
            case 0:
                // Top-level submenus get the 'nav-main-sub-list' class
                $class = 'nav-main-sub-list';
                break;
            case 1:
            case 2:
            case 3:
                // Submenus nested 1-3 levels deep get the 'nav-other-sub-list' class
                $class = 'nav-other-sub-list';
                break;
            default:
                // All other submenu `<ul>`s receive no class
                break;
        }

        // Only print out the 'class' attribute if a class has been assigned
        if( isset( $class ) )
            $output .= "\n$indent<ul class=\"$class\">\n";
        else
            $output .= "\n$indent<ul>\n";
    }

    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        $indent = str_repeat("\t", $depth);
        $attributes  = '';

        ! empty ( $item->attr_title )
        // Avoid redundant titles
        and $item->attr_title !== $item->title
        and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"';

        ! empty ( $item->url )
        and $attributes .= ' href="' . esc_attr( $item->url ) .'"';

        $attributes  = trim( $attributes );
        $title       = apply_filters( 'the_title', $item->title, $item->ID );
        $item_output = "$args->before<a $attributes>$args->link_before$title</a>"
                       . "$args->link_after$args->after";

        // Select a CSS class for this `<li>` based on $depth
        switch( $depth ) {
            case 0:
                // Top-level `<li>`s get the 'nav-main-item' class
                $class = 'nav-main-item';
                break;
            default:
                // All other `<li>`s receive no class
                break;
        }

        // Only print out the 'class' attribute if a class has been assigned
        if( isset( $class ) )
            $output .= $indent . '<li class="'. $class . '">';
        else
            $output .= $indent '<li>';

        $output .= apply_filters(
                'walker_nav_menu_start_el',
                $item_output,
                $item,
                $depth,
                $args
            );
    }
}
0
bosco