Exclure dynamiquement les éléments de menu de wp_nav_menu

15

J'ai essayé de rechercher des informations sur la manière d'exclure / de supprimer des éléments de menu de navigation des menus personnalisés, ainsi que le seul thread Je n'ai trouvé aucune réponse qui me soit utile.

1. Contexte:

J'ai créé un menu Dock à l'aide des menus personnalisés WP (wp_nav_menu) et jqDock sur mon site. Puisque jqDock a besoin d’images continues ou de liens d’images pour fonctionner comme par magie, j’utilise un marcheur personnalisé pour que la sortie HTML du menu de navigation ressemble au suivant:

<div id="menu-first" class="nav">
<a><img src="http://path/to/image-1.png"/></a><a><imgsrc="http://path/to/image-2.png"/></a>
<a><img src="http://path/to/image-3.png"/></a>etc...</div>

Lecodedemonlecteurpersonnaliséestlesuivant:

classcustom_nav_walkerextendsWalker_Nav_Menu{var$tree_type=array('post_type','taxonomy','custom');var$db_fields=array('parent'=>'menu_item_parent','id'=>'db_id');functionstart_lvl(&$output,$depth){$indent=str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }

    function end_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul>\n";
    }

    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;
        $classes[] = 'menu-item-' . $item->ID;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

        //$output .= $indent . '<li' . $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        ) .'"' : '';

        $description  = ! empty( $item->description ) ? esc_attr( strtolower( $item->description )) : '';
        $item_title   = ! empty( $item->attr_title )  ? esc_attr( $item->attr_title ) : '';

        if ( strpos($description, ';') !== false ) {
        $description_array = explode (';', $description);
            $image_name = $description_array[0];
            $image_alt = $description_array[1];
        } else {
            $image_name = $description;
            $image_alt = $item_title;
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .'<img src="'.get_bloginfo('template_url').'/images/skin1/'.$image_name.'" alt="'.$image_alt.'" title="'.$item_title.'" />'.$args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

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

    function end_el(&$output, $item, $depth) {
        $output .= "";
    }

}

Le script jqDock récupère ensuite l'ID de menu ('menu-first') et remplace la sortie wp_nav_menu par la sortie du menu Dock. La sortie HTML du menu Dock change en fonction des options spécifiées lors du chargement de jqDock.

2. La question:

Je ne souhaite pas afficher (c’est-à-dire exclure) certains éléments de menu en fonction de la position de l’utilisateur sur le site. Par exemple, je voudrais afficher uniquement l'élément Accueil lorsque l'utilisateur ne se trouve pas dans cet élément, et l'élément Publication aléatoire uniquement lorsqu'il l'est.

3. Solutions rejetées:

a. Plusieurs menus: L'enregistrement et la création de plusieurs menus, puis leur appel conditionnel pourraient fonctionner. Cependant, je ne pense pas qu'il s'agisse d'une solution idéale ni propre pour plusieurs raisons. De plus, il n’est pas facile de gérer ou de mettre à jour plusieurs menus.

b. Regex Search and Replace: Cela pourrait me forcer à modifier le paramètre needle chaque fois que je modifie les options jqDock car la sortie HTML est modifiée.

c. Propriété CSS 'display': Masquer les éléments à l'aide de la propriété d'affichage CSS fonctionne, mais puisqu'il doit être appliqué à la sortie du menu jqDock, cela affecte le rendu visuel du menu.

4. Solutions échouées:

a. Filtrez à wp_nav_menu_items : j'ai essayé d'attraper la variable '$ items' (chaîne) et de lui attribuer des valeurs différentes via des balises conditionnelles avec le code suivant:

function userf_dynamic_nav_menu ($items) {
    $items_array_home = explode('<a', $items);
    $items_array_nothome = $items_array_home;

    unset($items_array_home[1]);
    unset($items_array_nothome[2]);

    $items_home = implode('<a', $items_array_home);
    $items_nothome = implode('<a', $items_array_nothome);

    if ( is_home() ) {
        $items = $items_home;
    } else {
        $items = $items_nothome;
    }
    return $items;
}
add_filter('wp_nav_menu_first_items', 'userf_dynamic_nav_menu');

Cela ne fonctionne que partiellement, car les éléments de menu changent, mais les balises conditionnelles sont ignorées. Je suppose que cela a du sens en raison du moment où le filtre est appliqué.

b. Fonction de menu de navigation personnalisée : j'ai essayé de créer ma propre fonction de menu de navigation personnalisée afin de pouvoir ajouter un argument d'exclusion au tableau $ defaults et d'utiliser ce code légèrement modifié à partir de wp_list_pages pour renseigner l'argument supplémentaire:

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

Des idées?

    
posée Marventus 21.10.2011 - 19:14

2 réponses

25

Méthode 1

Vous pouvez ajouter un constructeur à votre Walker personnalisé pour stocker des arguments d'exclusion supplémentaires, tels que:

class custom_nav_walker extends Walker_Nav_Menu {
    function __construct( $exclude = null ) {
        $this->exclude = $exclude;
    }

    function skip( $item ) {
        return in_array($item->ID, (array)$this->exclude);
        // or
        return in_array($item->title, (array)$this->exclude);
        // etc.
    }

    // ...inside start_el, end_el
    if ( $this->skip( $item ) ) return;
}

Ou supprimez le constructeur et définissez sa propriété $exclude avant de le transmettre comme marcheur à wp_nav_menu() comme suit:

$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );

Selon ce que vous excluez, fournissez le formulaire correct à exclure.

Méthode 2

Voici comment procéder: vous vous connectez au filtre wp_get_nav_menu_items .

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    // Iterate over the items to search and destroy
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 168 ) unset( $items[$key] );
    }

    return $items;
}

add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );

Remarque: object_id est l'objet vers lequel le menu pointe, alors que ID correspond à l'ID de menu, ils sont différents.

Faites-moi savoir vos pensées.

    
réponse donnée soulseekah 21.10.2011 - 20:08
0

cela aide-t-il

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

à titre d'exemple

< ?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'exclude' => '66' ) ); ?>
    
réponse donnée saq 22.10.2011 - 02:11

Lire d'autres questions sur les étiquettes