web-dev-qa-db-fra.com

Comment masquer un élément d'un menu pour déconnecter les utilisateurs (sans plugin)

Je souhaite masquer un élément d'un menu si un utilisateur est déconnecté.

J'utilise actuellement le code ci-dessous, qui utilise deux menus distincts pour cela, mais pour éviter les doublons, je n’ai plus qu’à gérer un seul menu de navigation.

function my_wp_nav_menu_args( $args = '' ) {

    if ( is_user_logged_in() ) { 
        $args['menu'] = 'logged-in';
    } else { 
        $args['menu'] = 'logged-out';
    }

    return $args;
}
add_filter( 'wp_nav_menu_args', 'my_wp_nav_menu_args' );

Est-il possible de masquer un seul élément pour un utilisateur déconnecté, plutôt que de le faire tel que je suis actuellement?

2
Iqbal Mahmud

Comme @chrisguitarguy a déjà ajouté une réponse plus que valide pendant que j'écrivais cette réponse, voici un simple addition aux deux autres réponses.

La valeur return de la fonction wp_setup_nav_menu() a un filtre , dont $menu_item est la seule valeur fournie - exactement avant son renvoi - et il est de type object et un \stdClass avec les propriétés public suivantes que vous pouvez vérifier:

  • ID: Term_id si l'élément de menu représente un terme de taxonomie.
  • attr_title: attribut title de l'élément link pour cet élément de menu.
  • classes: le tableau des valeurs d'attribut de classe pour l'élément link de cet élément de menu.
  • db_id: l'ID de base de données de cet élément sous la forme d'un objet nav_menu_item, s'il existe (0 s'il n'existe pas).
  • description: description de cet élément de menu.
  • menu_item_parent: l'ID de la base de données de nav_menu_item qui est le parent du menu de cet élément, le cas échéant. 0 sinon.
  • object: Type d'objet représenté à l'origine, tel que "catégorie", "publication" ou "pièce jointe".
  • object_id: l'ID de base de données de l'objet d'origine que cet élément de menu représente, par exemple. ID pour les publications et term_id pour les catégories.
  • post_parent: l'ID de base de données de l'objet parent de l'objet d'origine, le cas échéant (0 sinon).
  • post_title: Une étiquette "pas de titre" si l'élément de menu représente un article sans titre.
  • target: attribut target de l'élément link pour cet élément de menu.
  • title: Le titre de cet élément de menu.
  • type: famille d'objets initialement représentés, tels que "post_type" ou "taxonomy".
  • type_label: L'étiquette singulière utilisée pour décrire ce type d'élément de menu.
  • url: URL vers laquelle cet élément de menu pointe.
  • xfn: La relation XFN exprimée dans le lien de cet élément de menu.
  • _invalid: Indique si l'élément de menu représente un objet qui n'existe plus.

Donc, un simple rappel vous permettra d’utiliser une logique conditionnelle et d’exclure éventuellement un élément:

add_filter( 'wp_setup_nav_menu', function( \stdClass $item ) {
    # Check conditionals, and invalidate an item in case
    $item->_invalid = is_user_logged_in() 
        && 'post' === $item->object
        && 'post_type' === $item->type
        # && … whatever you need to check for your invalidation of an item
    ;

    return $item;
} );

La logique d'exclusion réside dans la propriété _invalid et est exécutée par la fonction _is_valid_nav_menu_item( $item ) qui est un rappel utilisé lorsque les éléments de menu nav sont extraits . Il l’utilise dans une array_filter() pour réduire le nombre d’éléments dépendant de ce flag .


En tant qu'extension de la solution @MD Sultan Nasir Uddin: Bien qu'une solution CSS ne fonctionne que, l'objectif devrait être de ne même pas avoir les données dans cette requête, dans la requête de base de données et dans le pipeline de rendu. Pour une réponse complète, voici encore le comment : Exemple utilisant wp_add_inline_style() pour insérer les styles et PHP syntaxe heredoc pour des raisons de lisibilité:

<?php
/** Plugin Name: Hide menu items for logged in users */

# Add class:
add_filter( 'wp_nav_menu_args', function( Array $args ) {
    if ( is_user_logged_in() )
        $args['menu_class'] .= '  logged-in';
    return $args;
} );

# Add inline styles
add_action( 'wp_enqueue_scripts', function() {

    $styles = <<<STYLES
.logged-in .special-item {
    display: none;
}
STYLES;

    wp_add_inline_style( 'custom-style', $styles );
} );

Vous pouvez probablement simplement utiliser les classes body pour rechercher également une logged-in ou une classe similaire pour une cible plus spécifique - au lieu d’ajouter une classe supplémentaire comme ci-dessus.

3
kaiser

Après cela, je le fais en utilisant CSS nth enfant la procédure est

add_action('wp_head','hide_menu');

function hide_menu() { 
    if ( is_user_logged_in() ) {
        //
    } else {
        $output="<style> .menu li:nth-child(3) { display: none; } </style>";
    }
    echo $output;
}

Merci à vous tous pour vos efforts :)

2
Iqbal Mahmud

Filtre wp_nav_menu_objects . Il contiendra la liste triée des éléments de menu de navigation à rendre. Consultez wp_setup_nav_menu_item pour connaître certaines propriétés que vous pouvez utiliser.

Voici un exemple rapide (non testé).

add_filter( 'wp_nav_menu_objects', function( array $items, array $args ) {

    if ( 'someThemeLocation' !== $args->theme_location ) {
        return $items;
    }

    return array_filter( $items, function( $item ) {
        return '/user-specific-thingy' === $item->url 
            && ! is_user_logged_in();
    } );

}, 10, 2 );
2
chrisguitarguy