web-dev-qa-db-fra.com

Modifier le contenu d'un élément de liste dans la navigation de menu pour ajouter un élément enfant avec une classe spécifique

Cela fait un moment que je suis absent de wordpress et je n'ai jamais autant pratiqué. J'ai quelques problèmes même si j'ai cherché sur Internet une réponse ... concernant le comportement de wp_nav_menu.

J'espère que vous pourrez m'aider et comprendre mon anglais.

Le problème est le suivant: Version abrégée: j'essaie de réécrire la manière dont <li> sera généré à partir de PHP dans le code HTML. À l'heure actuelle, c'est le moyen par défaut de Wordpress de générer la navigation. Il y a un nav -> ul -> li -> a. J'essaie avec le filtre de retravailler le li pour avoir quelque chose comme <li><a href="#' . $url . '"><span>' . $title . '</span><i class="fa ' . $list_ico_class . '"/></a></li> Vous pouvez voir cette dernière ligne à la fin du filtre :)

Version longue: j'ai une navigation principale qui affiche les catégories d'un type de message personnalisé "projets" (faisant une nouvelle version de mon portefeuille). J'aurais probablement 3 catégories: Design, Frontend, Applications. Les éléments de menu seraient alors ces 3 catégories + un lien de blog.

J'essaie d'ajouter une classe personnalisée pour chaque élément de la liste en fonction du titre de l'élément. Après avoir regardé sur Internet, la solution semblait être de créer une fonction permettant de filtrer le contenu.

J'ai écrit ce qui suit basé sur différentes sources:

add_filter( 'wp_nav_menu_items', 'my_custom_menu_item', 10, 2 );
function my_custom_menu_item ( $items, $args ) {
    if (is_single() && $args->theme_location == 'primary') {
        foreach ( (array) $menu_items as $key => $menu_item ) {
            $title = $menu_item->title;
            $url = $menu_item->url;

            if ($title == 'Design') {
                $list_ico_class = 'fa-pencil';
            }
            else if ($title == 'Frontend') {
                $list_ico_class = 'fa-desktop';
            }
            else if ($title == 'Applications') {
                $list_ico_class = 'fa-code';
            }
            else if ($title == 'Blog') {
                $list_ico_class = 'fa-user';
            }
            else {
                $list_ico_class = 'fa-question';
            }

            $menu_list .= '<li><a href="#' . $url . '"><span>' . $title . '</span><i class="fa ' . $list_ico_class . '"/></a></li>';
        }
    }
    return $menu_items;
}

Ensuite, dans mon modèle header.php, j’ai fait le menu de manière "régulière" car je ne suis pas sûr de savoir comment procéder.

<nav class="site-navigation main-navigation">
                <span class="nav-info">Smoothly go to<i class="fa fa-long-arrow-right"></i></span>
                <?php

                    $main_nav_values = array(
                        'theme_location'  => 'primary',
                        'menu'            => '',
                        'container'       => 'false',
                        'container_class' => '',
                        'container_id'    => '',
                        'menu_class'      => 'main-navigation', 'site-navigation',
                        'menu_id'         => 'primary-menu',
                        'echo'            => true,
                        'fallback_cb'     => 'wp_page_menu',
                        'before'          => '',
                        'after'           => '',
                        'link_before'     => '',
                        'link_after'      => '',
                        'items_wrap'      => '<ul id="%1$s">%3$s</ul>',
                        'depth'           => 0,
                        'walker'          => ''
                    );

                    wp_nav_menu($main_nav_values);

                    ?>
            </nav> <!-- .site-navigation .main-navigation -->

Le menu n'apparaît plus, malheureusement, lorsque la fonction de filtrage est présente ... Ne provoque aucune erreur, probablement juste un objet null?

J'ai essayé de suivre ce qui est suggéré ici: http://codex.wordpress.org/Plugin_API/Filter_Reference/nav_menu_css_class et là Obtenir slug élément de menu

La sortie souhaitée serait la suivante:

<nav class="site-navigation main-navigation">
        <span class="nav-info">Smoothly go to<i class="fa fa-long-arrow-right"></i></span>
        <ul>
            <li><a href=""><span>Design</span><i class="fa fa-pencil"></i></a></li>
            <li><a href=""><span>Frontend development</span><i class="fa fa-desktop"></i></a></li>
            <li><a href=""><span>Application & Games</span><i class="fa fa-code"></i></a></li>
            <li><a href=""><span>Blog</span><i class="fa fa-user"></i></a></li>
        </ul>
    </nav> <!-- .site-navigation .main-navigation -->

Une idée de ce que serait mon erreur? merci d'avance, n'hésitez pas à demander si plus de détails sont nécessaires!

1
JetXS

Trouvé la réponse.

Ce n'est peut-être pas la meilleure façon de le faire, mais cela fonctionne pour le moment.

Je cherchais à utiliser un filtre lorsque la solution semble utiliser un marcheur personnalisé.

class edited_menu_walker extends Walker_Nav_Menu {
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $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 ) . '"';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $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        ) .'"' : '';

        //Store the span in a variable
        $prepend = '<span>';

        //Check the title of the item, deduct the class name needed for FontAwesome
        if ($item->title == 'Design') {
            $theIcoName = 'fa-pencil';
        } else if ($item->title == 'Frontend') {
            $theIcoName = 'fa-desktop';
        } else if ($item->title == 'Applications') {
            $theIcoName = 'fa-code';
        } else if ($item->title == 'Blog') {
            $theIcoName = 'fa-user';
        } else {
            $theIcoName = 'fa-question';
        }

        //Create the FontAwesome ready <i> element
        $ico = '<i class="fa '.$theIcoName.'"></i>';

        //Close the span and add the calculated icon
        $append = '</span>'.$ico;

        if($depth != 0) {
            $ico = $append = $prepend = "";
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append; //add prepend to open the span storing the title, append to close this span and add the FontAwesome icon in an <i> element
        $item_output .= $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

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

Vous devez ajouter ce code dans votre fichier function.php.

La première moitié du code est le "wordpress walker original". Sur la seconde moitié, où le code est un peu commenté, j'ai fait de la "cuisine".

Pour stocker le texte (titre de l'élément) de l'élément de menu, je crée une variable '$ prepend' ouvrant l'élément span.

Après cela, j’ai écrit quelques conditions qui détermineront, en fonction du titre de l’article, quelle devrait être la classe de l’élément '' utilisé pour afficher l’icône de FontAwesome.

Si aucun titre n'est trouvé dans la liste, un point d'interrogation sera affiché par défaut avec la classe 'fa-question'. C'est mon "filet de sécurité" pour remarquer que quelque chose s'est passé dans mon template et que je dois modifier mon code pour une éventuelle nouvelle icône/un nouvel élément de menu.

Lorsque cette déduction est faite, nous créons la variable '$ append' qui fermera le '' mais en ajoutant aussi juste après le + suivant de fa, la classe correcte.

Nous construisons finalement la sortie à la fin avec '$ item_output =' entre ''.

J'espère que c'est assez clair. Si quelqu'un a une meilleure solution, n'hésitez pas à le partager.

1
JetXS