web-dev-qa-db-fra.com

Vérifiez ce que "type" un élément de menu est

La question

Je voudrais vérifier quel type d’élément de menu chaque élément de mon menu est c’est-à-dire un lien de page, de catégorie ou personnalisé.

Ce que je veux réaliser

Je veux créer un menu composé de catégories et de liens de pages. Parmi les catégories du menu, je souhaite uniquement afficher celles qui contiennent des publications. Les liens de page seront toujours montrer.

Ce menu sera utilisé sur un site de commerce électronique avec un catalogue qui change constamment. Faire un menu dynamique qui cache les catégories vides supprime la nécessité de mettre à jour constamment le menu dans la zone d'administration.

Ce que j'ai maintenant

Un menu personnalisé basé sur ce SE post qui masque avec succès les liens vers les catégories vides en ajoutant une logique à la fonction start_el. Malheureusement, ma logique cache aussi des liens de pages

Fonction complète du menu du marcheur:

function cs_modify_nav_menu_args( $args ){
if( 'primary-menu' == $args['theme_location'] ){
    $args['walker'] = new cs_walker_nav_menu();
}
return $args;
}

class cs_walker_nav_menu extends Walker_Nav_Menu {
// filter empty categories and add main/sub classes to li's and links
function start_el(  &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
    global $wp_query;


    if(!is_page($item->ID)){

        $non_empty_categories = get_categories(array('taxonomy' => 'product_cat'));
        $empty_categories = array();
        $is_empty = true;
        // check menu items are for an empty category
        foreach ( $non_empty_categories as $cat )
            if ($item->object_id === $cat->term_id)
                $is_empty = false;
            // if it is empty add it to array
            if ($is_empty)
                $empty_categories[] = $item->ID;
        // Don't build nav item for items in the is_empty array
        foreach( $empty_categories as $category_to_skip )
            if( $item->ID == $category_to_skip )
                return $output;
    }

    $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent

    // depth dependent classes
    $depth_classes = array(
        ( $depth == 0 ? 'main-menu-item' : 'sub-menu-item' ),
        ( $depth >=2 ? 'sub-sub-menu-item' : '' ),
        ( $depth % 2 ? 'menu-item-odd' : 'menu-item-even' ),
        'menu-item-depth-' . $depth
    );
    $depth_class_names = esc_attr( implode( ' ', $depth_classes ) );

    // passed classes
    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );

    // build html
    $output .= $indent . '<li id="nav-menu-item-'. $item->ID . '" class="' . $depth_class_names . ' ' . $class_names . '">';

    // link attributes
    $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        ) .'"' : '';
    $attributes .= ' class="menu-link ' . ( $depth > 0 ? 'sub-menu-link' : 'main-menu-link' ) . '"';

    $item_output = sprintf( '%1$s<a%2$s>%3$s%4$s%5$s</a>%6$s',
        $args->before,
        $attributes,
        $args->link_before,
        apply_filters( 'the_title', $item->title, $item->ID ),
        $args->link_after,
        $args->after
    );

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

Solutions tentées

L'objet nav_menu_item ne fournit pas le type d'élément de menu.

Passer $item->ID à is_page ne retourne pas. Je crois que $item->ID est l'ID de l'élément de menu et non un ID de publication.

2
Andrew

Heureusement, il existe une solution facile à cela.

Le $item dans Walker fournit des classes, et si l'élément de menu est une archive, vous obtenez l'une de celles-ci:

  • menu-item-type-taxonomy (général)
  • menu-item-object-product_cat (product_cat == taxonomyname)

aussi bien que

  • $ item-> type == 'taxonomie'
  • $ item-> object == 'votre_taxonomie'

Si vous voulez que cette logique fonctionne pour différentes archives (pas uniquement le product_cat), vous devez également modifier la taxonomie - là encore, $item délivre commodément votre taxonomie $ en tant que $item->object.

Maintenant, il vous suffit de changer votre if et la taxonomie dans votre Walker

if( $item->type == 'taxonomy' ) {

    $non_empty_categories = get_categories( array( 'taxonomy' => $item->object ) );

    // ... The rest of your logic works fine

}

Devrait fonctionner très bien :)

1
fischi