Comment consolider le comportement du menu pour vos CPT

Comment consolider le comportement du menu pour vos CPT ?

Cet article fait suite au précédent, dans lequel je donne un exemple de contournement pour créer une page d’archive de custom post type personnalisée. Lorsque vous créez un custom post type, WordPress en effet va générer automatiquement une page d’archive que vous pourrez retrouver dans l’onglet Apparence / menu. C’est une page qui n’existe pas en dur dans le dossier wordpress, et qu’on ne peut malheureusement pas personnaliser.

On a donc vu comment contourner cette contrainte, en créant un modèle de page qui prend le rôle de page d’archive.

Le problème

Le problème, c’est qu’il reste à modifier le comportement du menu wordpress qui se perd un peu dans l’arborescence. Il se peut que wordpress souligne la page blog lorsque vous êtes dans un article de custom post type, comme si la page blog était parente de vos CPT.

Pour contourner ce dysfonctionnement, et si vous avez placé votre page d’archive personnalisée dans le menu, voici le code à insérer dans functions.php

La solution

Ce code vous permettra, lorsque vous êtes dans une page single CPT, de surligner le modèle de page plutôt que la page blog, comme s’il s’agissait d’une page d’archive parente classique.


/* PREVENT BLOG CURENT MENU ITEM CLASS ON CPT*/
add_filter( 'nav_menu_css_class', 'theme_remove_cpt_blog_class', 10, 3 );
function theme_remove_cpt_blog_class( $classes, $item, $args ) {
if( !is_singular( 'post' ) AND !is_category() AND !is_tag() AND !is_date() ):
$blog_page_id = intval( get_option( 'page_for_posts' ) );
if( $blog_page_id != 0 AND $item->object_id == $blog_page_id )
unset( $classes[ array_search( 'current_page_parent', $classes ) ] );
endif;
return $classes;
}

/* ADD CURRENT MENU ITEM CLASS ON CPT PARENT PAGE */
add_action( 'nav_menu_css_class', 'theme_add_cpt_ancestor_class', 10, 3 );
function theme_add_cpt_ancestor_class( $classes, $item, $args ) {
global $post;
$current_post_type = get_post_type_object( get_post_type( $post->ID ) );
$current_post_type_slug = $current_post_type->rewrite[ 'slug' ];
$menu_slug = strtolower( trim( $item->url ) );
if( strpos( $menu_slug, $current_post_type_slug ) !== false )
$classes[] = 'current_page_parent';
return $classes;
}

Cette action et ce filtre permettent de retirer la classe current_page_parent que wordpress attribue automatiquement à la page blog, et de la réattribuer à votre modèle de page.

L’utilisateur ne verra donc plus aucune différence entre le modèle de page et une vraie page d’archive.