web-dev-qa-db-fra.com

L'élément de menu ajouté au filtre wp_nav_menu_items n'est jamais mis en surbrillance

Dans un thème pour enfants de treize ans, j'ajoute un élément de menu (un lien vers le modèle de page /player-number , où le numéro est différent pour chaque utilisateur et représente son identifiant dans une base de données de jeu) à l'aide de wp_nav_menu_items crochet:

function my_nav_menu_items( $items ) {
    $profile = sprintf('<li id="menu-item-32" 
        class="menu-item menu-item-type-custom 
        menu-item-object-custom menu-item-32">
        <a href="/player-%d/#navbar">Profile</a></li>', 
        42); // 42 is just a placeholder here, representing user id

    return $items . $profile;
}

add_filter( 'wp_nav_menu_items', 'my_nav_menu_items' );

Et cet élément est visible et cliquable dans le primary-menu, mais pour une raison quelconque, il n'est jamais mis en surbrillance (excuses du texte non anglais dans la capture d'écran):

 website screenshot 

C'est à dire. lorsque je clique sur une autre entrée du menu, sa couleur devient rougeâtre et la police inclinée devient italique:

 highlighted menu item 

Mais le dernier élément du menu ne fait pas cela, pourquoi?

UPDATE:

Le filtre wp_nav_menu_objects semble mieux convenir à la tâche d’ajout d’un élément de menu et j’ai essayé de l’utiliser dans mon /wp-content/themes/twentythirteen-child/functions.php file:

function my_nav_menu_objects( $sorted_menu_items ) 
{
    $link = array (
        'title'            => 'Profile',
        'menu_item_parent' => 0,
        'ID'               => 32,
        'url'              => '/player-42',
    );
    $sorted_menu_items[] = (object) $link;
    error_log(print_r($sorted_menu_items, TRUE));
    return $sorted_menu_items;
}

add_filter( 'wp_nav_menu_objects', 'my_nav_menu_objects' );

mais le problème est le même: l’élément de menu est ajouté, mais il n’est pas mis en surbrillance (le style CSS current-menu-item qui manque) lorsque sélectionné.

UPDATE 2:

J'ai aussi essayé d'ajouter un élément de menu appelé "Profil" manuellement, puis de rechercher et de remplacer sa url par le code suivant:

function my_nav_menu_objects( $sorted_menu_items )
{
    foreach ( $sorted_menu_items as $item ) {
            error_log(print_r($item, TRUE));

            if ( $item->title == 'Profile' ) {
                $item->url = '/player-42';
                break;
            }
    }

    return $sorted_menu_items;
}

add_filter( 'wp_nav_menu_objects', 'my_nav_menu_objects' );

avec le même effet (l'URL a changé, mais la mise en surbrillance CSS est manquante lorsque cette URL est sélectionnée).

1
Alexander Farber

@AlexanderFarber _, il existe de nombreuses façons d'attacher une classe d'attribut sous wp_nav_menu link. Je suis d’accord avec @Sumit _, l’ajout de liens de page dans Appearance > Menu WordPress prend en charge la classe current-menu-item ou la classe current_page_item. Cette méthode est également recommandée pour gérer votre menu de navigation à l’avenir.

Créer un lien dynamique dans wp_nav_menu

Depuis votre question liée à cette réponse , alors vous avez un Page avec player comme slug. Mon approche, après avoir ajouté ces pages en tant que menu dans Appearance > Menu (puis changer le libellé avec 'Profil'), je vais utiliser le filtre nav_menu_link_attributes pour que cette page ait un lien dynamique. En tant que question, vous utilisez l’identifiant d’utilisateur actuel pour le rendre dynamique. Jetez un coup d'œil à cet exemple de code, par exemple, 7 est la publication/l'ID de la page comme cible:

add_filter( 'nav_menu_link_attributes', function( $atts, $item, $args, $depth )
{
    // check our nav_menu
    if ( is_object( $args ) && is_object( $item ) && 'primary-menu' == $args->menu_id )
    {
        $post_id = 7; // Define Post or Page ID
        $user    = wp_get_current_user();
        if ( 0 < $user->ID && $post_id == $item->object_id )
            $atts['href'] = esc_url( user_trailingslashit( untrailingslashit( $item->url ) . '-' . $user->ID ) );
    }
    return $atts;
} 10, 4 );

Vous devez vérifier quel menu avant de faire des modifications, car votre filtre effectuera un autre menu dans la même page. Grâce à cette approche, vous ne rencontrez aucun problème dans les attributs (liés à la classe ou au thème id) de la page en cours.

Réponse liée votre code

Oui, je sais que vous devez ajouter un lien personnalisé par filtre wp_nav_menu_items et ajouter un attribut de classe pour la page en cours, presque identique à votre réponse. Puisqu'il se rapporte à Page, j'utilise current_page_item comme attribut de classe qui correspond au css TwentyThirteen pour mettre en surbrillance le menu de navigation des éléments.

add_filter( 'wp_nav_menu_items', 'my_nav_menu_items', 10, 2 );
function my_nav_menu_items( $items, $args )
{
    if ( is_object( $args ) && 'primary-menu' == $args->menu_id )
    {
            $user         = wp_get_current_user();
            $with_user_id = ( 0 != $user->ID ) ? '-' . $user->ID : '';

            $post_id      = 7; // Post or Page ID
            $class        = ( is_page( $post_id ) ) ? 'current_page_item' : '';

            $items .= sprintf( '<li id="menu-item-32" class="menu-item menu-item-type-custom 
            menu-item-object-custom %1$s menu-item-32"><a href="%2$s">%3$s</a></li>',
                sanitize_html_class( $class ),
                esc_url( user_trailingslashit( untrailingslashit( get_page_link( $post_id ) ) . $with_user_id  ) ),
                __( 'Profile', 'textdomain' )
            );
    }
    return $items;
}

Vous pouvez modifier le code pour l'adapter à votre projet actuel. J'espère que ça aide.

1
Jevuska

Les autres pages affichent l'état "élément de menu actuel":

.nav-menu .current_page_item > a, .nav-menu .current_page_ancestor > a, .nav-menu .current-menu-item > a, .nav-menu .current-menu-ancestor > a {
   color: #bc360a;
   font-style: italic;

Cette page s'affiche sous le nom "page-id-32". Si cela correspond à la page du menu, le css "élément de la page en cours" devrait apparaître. Sinon, vous devez obtenir l'élément 'current-menu-item' de la classe dans le css lorsque vous êtes sur cette page. Par exemple, si vous changez:

sprintf('<li id="menu-item-32" 
    class="menu-item menu-item-type-custom 
    menu-item-object-custom menu-item-32">

à

sprintf('<li id="menu-item-32" 
    class="menu-item menu-item-type-custom 
    menu-item-object-custom current-menu-item">

Cela fera le travail, mais je pense que cela montrerait comme "toujours" la page actuelle.

0
Monkey Puzzle

Voici ma propre solution - dans le fichier /wp-content/themes/twentythirteen-child/functions.php file, ajoutez le style CSS current-menu-item si le slug de page est player:

function my_nav_menu_items( $items ) 
{
    $profile = sprintf('<li class="menu-item 
        menu-item-type-custom 
        menu-item-object-custom 
        %s"><a href="/player-%d/#navbar">Profile</a></li>', 
        ( is_page( 'player' ) ? 'current-menu-item' : '' ),
        42);
    return $items . $profile;
}

add_filter( 'wp_nav_menu_items', 'my_nav_menu_items' );

Une vérification de page plus spécifique serait: is_page( array ( 42, 'player' ) )

0
Alexander Farber