Les menus de navigation personnalisés sont une fonctionnalité WordPress étonnante qui permet aux utilisateurs-administrateurs d’ajouter n’importe quelle liste de liens n’importe où dans le site. Il peut s’agir de liens vers des ressources internes, comme des articles, des pages et des archives, ainsi que de liens vers des ressources externes, comme vos pages de profils sociaux. WordPress réserve une page d’administration spécifique aux menus de navigation personnalisés. Dans cette page, l’utilisateur-administrateur peut créer des menus, organiser des éléments et définir des propriétés qui affectent la façon dont ils apparaissent dans l’interface publique.

Écran WordPress d'apparence des menus

Écran WordPress d’apparence des menus

Cela dit, les principales questions qui se cachent derrière cet article sont : « Peut-on améliorer les fonctionnalités intégrées de l’écran des menus ? »
Bien sûr que l’on peut. Je vais donc plonger profondément dans le sujet, et je vais disséquer les sections et les objets qui permettent d’ajouter et de gérer les menus et leurs éléments. Mais ce ne sera pas seulement une description de l’écran. Je vais vous montrer comment ajouter des éléments personnalisés au menu accordéon situé dans la colonne latérale de gauche.

Ces boîtes personnalisées afficheront des listes de liens supplémentaires parmi lesquels choisir lors de la création de menus de navigation personnalisés. Plus spécifiquement, je vous montrerai comment ajouter une boîte contenant des liens vers les archives des auteurs du site.
Commençons à plonger dans la construction d’un menu WordPress personnalisé.

L’écran d’apparence des Menus

La page de modification des menus permet aux utilisateurs de créer et de gérer des menus personnalisés grâce à une interface intuitive. Le bouton « Options de l’écran » dans le coin supérieur droit dévoile la première section de la page qui contient deux groupes de cases à cocher. Le groupe Sections permet à l’utilisateur de masquer et d’afficher les méta-boîtes de menu dans la colonne latérale de gauche, tandis que le groupe Afficher les propriétés avancées du menu masque et affiche les propriétés comme les cibles de liens, les descriptions et les classes CSS pour les éléments de la liste.

Onglet des options d'écran

Onglet des Options d’écran

Une fois le premier menu créé, l’écran Menus est légèrement différent de son apparence par défaut. De nouvelles sections apparaissent dans l’onglet Modifier les menus.

  • La section supérieure propose un menu de sélection et un lien de création d’un nouveau menu ;
  • La colonne de gauche contient un menu en accordéon contenant les méta-boîtes d’éléments de menu disponibles. Ces méta-boîtes contiennent des éléments sélectionnés parmi les pages, les articles, les catégories, les étiquettes, les taxonomies, les types de publications et les formats d’articles (prochainement, les types de publications personnalisés et les taxonomies).
  • La section Structure du menu contient les modules d’éléments de menu à partir desquels l’utilisateur peut organiser les liens et définir leurs attributs et propriétés.
  • La section Réglages des menus fournit une liste de cases à cocher qui relient les menus aux emplacements des thèmes enregistrés.
Les méta-boîtes d'éléments de menu intégrées affichent des listes de liens pointant vers le contenu du site.

Les méta-boîtes d’éléments de menu intégrées affichent des listes de liens pointant vers le contenu du site.

Méta-boîtes et Modules

La colonne latérale gauche de l’écran Menus contient un menu accordéon dont les éléments sont nommés méta-boîtes d’éléments de menu. Ces blocs fournissent un certain nombre de champs de formulaire et de contrôles qui permettent à l’utilisateur de rechercher le contenu du site et d’ajouter des liens aux menus de navigation.
Par défaut, WordPress fournit les méta-boîtes de menu suivantes :

Lorsque l’utilisateur ajoute un lien à un menu, un nouveau module d’éléments est ajouté à la section Structure du menu de l’écran. WordPress fournit quatre typologies de modules d’éléments de menu :

  • Module Type d’article (articles, pages et types de publications personnalisés) ;
  • Module d’archive de type d’articles;
  • Module Taxonomie (pour les catégories, les étiquettes, les taxonomies personnalisées et les formats d’articles) ;
  • Module Liens personnalisés.
Comparaison des modules d'éléments de menu

Comparaison des modules d’éléments de menu

Nous allons étendre la structure intégrée de l’écran d’apparence des menus avec des méta-boîtes personnalisées qui permettraient à l’utilisateur-administrateur de sélectionner des éléments de contenu non disponibles par défaut, comme les archives des auteurs.
Malheureusement, l’API du menu de navigation de base n’est pas documentée et pour atteindre notre objectif, il était nécessaire de disséquer ligne par ligne deux fichiers de base : /wp-admin/includes/nav-menu.php pour les méta-boîtes de menu, et /wp-includes/nav-menu.php pour les modules d’éléments de menu.

Créer une Méta-boîte de Menu Personnalisée WordPress

Créez une nouvelle extension et ajoutez le code suivant au fichier principal :

/**
 * Add menu meta box
 *
 * @param object $object The meta box object
 * @link https://developer.wordpress.org/reference/functions/add_meta_box/
 */
function custom_add_menu_meta_box( $object ) {
	add_meta_box( 'custom-menu-metabox', __( 'Authors' ), 'custom_menu_meta_box', 'nav-menus', 'side', 'default' );
	return $object;
}
add_filter( 'nav_menu_meta_box_object', 'custom_add_menu_meta_box', 10, 1);

La fonction WordPress add_meta_box enregistre les méta-boîtes dans les pages d’administration. Elle conserve les arguments suivants :

Argument Type Description
$id chaîne (obligatoire) l’ID de la méta-boîte
$callback appelable (obligatoire) la fonction qui fait écho au contenu de la méta-boîte
$screen chaîne|tableau|WP_Screen (facultatif) l’écran sur lequel afficher la méta-boîte
$context chaîne (facultatif) le contexte à l’intérieur de l’écran où la boîte de méta doit afficher (les valeurs possibles sont « normal », « side », « advanced », par défaut « advanced »)
$priority chaîne (facultatif) Valeurs possibles : « high », « low », « default ».
$callback_args tableau (facultatif) un tableau d’arguments à passer au callback

Peut-être que vous vous attendiez à ce que la fonction add_meta_box soit hookée à une action comme add_meta_boxes, qui est déclenchée dans les pages de modification d’article. Malheureusement, nous n’avons pas d’action dans nav-menus.php à laquelle nous pouvons hooker la fonction, donc nous sommes obligés d’utiliser le filtre nav_menu_meta_box_object. Ce hook détermine si une méta-boîte d’éléments de menu sera ajoutée pour un type d’objet. Lorsque le filtre s’exécute, add_meta_box enregistre la méta-boîte personnalisée.
Nous pouvons maintenant définir la fonction de rappel qui produira le contenu HTML de la méta-boîte.

/**
 * Displays a metabox for an author menu item.
 *
 * @global int|string $nav_menu_selected_id (id, name or slug) of the currently-selected menu
 */
function custom_menu_meta_box(){
	global $nav_menu_selected_id;
	$walker = new Walker_Nav_Menu_Checklist();
	...
}

La variable globale garde en mémoire l’ID du menu courant, tandis que $walker stocke une nouvelle instance de l’objet Walker_Nav_Menu_Checklist, qui construit la liste HTML des éléments du menu.
Ensuite, nous devons définir la valeur de la variable $current_tab qui déterminera l’onglet actif dans la boîte méta. Pour faciliter les choses, je ne fournirai que deux onglets :

$current_tab = 'all';
if ( isset( $_REQUEST['authorarchive-tab'] ) && 'admins' == $_REQUEST['authorarchive-tab'] ) {
	$current_tab = 'admins';
}elseif ( isset( $_REQUEST['authorarchive-tab'] ) && 'all' == $_REQUEST['authorarchive-tab'] ) {
	$current_tab = 'all';
}

Par la suite, nous obtiendrons tous les utilisateurs avec des privilèges d’écriture, en ajoutant un certain nombre de propriétés à l’objet $authors.

$authors = get_users( array( 'orderby' => 'nicename', 'order' => 'ASC', 'who' => 'authors' ) );
$admins = array();

/* set values to required item properties */
foreach ( $authors as &$author ) {
	$author->classes = array();
	$author->type = 'custom';
	$author->object_id = $author->nickname;
	$author->title = $author->nickname . ' - ' . implode(', ', $author->roles);
	$author->object = 'custom';
	$author->url = get_author_posts_url( $author->ID ); 
	$author->attr_title = $author->displayname;
	if( $author->has_cap( 'edit_users' ) ){
		$admins[] = $author;
	}
}
$removed_args = array( 'action', 'customlink-tab', 'edit-menu-item', 'menu-item', 'page-tab', '_wpnonce' );
?>

get_users retourne un tableau d’objets $user sélectionnés par les paramètres spécifiés. Le paramètre who force WordPress à interroger la base de données uniquement pour les utilisateurs ayant des droits d’écriture.
Le tableau $admins stockera un tableau d’auteurs, tandis que la dernière variable, $removed_args, stockera une liste des variables de requête à supprimer.
Quand nous en aurons fini avec les données, nous pourrons afficher la balise de la méta-boîte. Tout d’abord, nous allons construire des labels d’onglets et des liens :

<div id="authorarchive" class="categorydiv">
	<ul id="authorarchive-tabs" class="authorarchive-tabs add-menu-item-tabs">
		<li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>>
			<a class="nav-tab-link" data-type="tabs-panel-authorarchive-all" href="<?php if ( $nav_menu_selected_id ) echo esc_url( add_query_arg( 'authorarchive-tab', 'all', remove_query_arg( $removed_args ) ) ); ?>#tabs-panel-authorarchive-all">
				<?php _e( 'View All' ); ?>
			</a>
		</li><!-- /.tabs -->

		<li <?php echo ( 'admins' == $current_tab ? ' class="tabs"' : '' ); ?>>
			<a class="nav-tab-link" data-type="tabs-panel-authorarchive-admins" href="<?php if ( $nav_menu_selected_id ) echo esc_url( add_query_arg( 'authorarchive-tab', 'admins', remove_query_arg( $removed_args ) ) ); ?>#tabs-panel-authorarchive-admins">
				<?php _e( 'Admins' ); ?>
			</a>
		</li><!-- /.tabs -->
	</ul>

Nous devons être prudents et assigner les noms de classes, ID et attributs de données corrects aux éléments de la méta-boîte. En cas d’erreur, le menu accordéon ne fonctionnera pas correctement.
Nous avons utilisé les fonctions add_query_arg et remove_query_arg pour définir des valeurs spécifiques aux onglets pour les variables de requête de l’onglet authorarchive-tab et supprimer les variables de requête inutiles.
L’image ci-dessous montre les labels des onglets résultants.

Onglets WordPress de menu personnalisés pour les auteurs

Onglets WordPress de menu personnalisés pour les auteurs

Ensuite, nous allons construire le contenu HTML des onglets (encore une fois, faites attention aux noms de classes et aux ID) :

<div id="tabs-panel-authorarchive-all" class="tabs-panel tabs-panel-view-all <?php echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); ?>">
	<ul id="authorarchive-checklist-all" class="categorychecklist form-no-clear">
	<?php
		echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $authors), 0, (object) array( 'walker' => $walker) );
	?>
	</ul>
</div><!-- /.tabs-panel -->

<div id="tabs-panel-authorarchive-admins" class="tabs-panel tabs-panel-view-admins <?php echo ( 'admins' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); ?>">
	<ul id="authorarchive-checklist-admins" class="categorychecklist form-no-clear">
	<?php
		echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $admins), 0, (object) array( 'walker' => $walker) );
	?>
	</ul>
</div><!-- /.tabs-panel -->

Chaque onglet contient une liste de cases à cocher. Cette liste est affichée par l’arbre walk_nav_menu_tree qui conserve les trois arguments suivants :

Argument Type Description
$items tableau (obligatoire) Un tableau d’éléments de menu
$depth int (obligatoire) le nombre de niveaux de la hiérarchie à inclure
$r objet (obligatoire) Instance d’une classe Walker_Nav_Menu_Menu_Checklist personnalisée

$items stocke le tableau des utilisateurs administrateurs. La fonction array_map applique l’élément wp_setup_nav_menu_menu_item à $admins, en ajoutant les propriétés des éléments de menu aux éléments du tableau.
L’image suivante montre la liste des auteurs qui en résulte.

Le premier onglet de la case à cocher affichera la liste complète des auteurs ayant la capacité d'écriture

Le premier onglet de la case à cocher affichera la liste complète des auteurs ayant la capacité d’écriture

Nous pouvons maintenant ajouter le bouton de validation et une animation.

<p class="button-controls wp-clearfix">
	<span class="list-controls">
		<a href="<?php echo esc_url( add_query_arg( array( 'authorarchive-tab' => 'all', 'selectall' => 1, ), remove_query_arg( $removed_args ) )); ?>#authorarchive" class="select-all"><?php _e('Select All'); ?></a>
	</span>
	<span class="add-to-menu">
		<input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-authorarchive-menu-item" id="submit-authorarchive" />
		<span class="spinner"></span>
	</span>
</p>

</div><!-- /.categorydiv -->
<?php
}

Le lien dans le premier élément de span permet de sélectionner toutes les cases à cocher de la liste, grâce au selectall d’argument de requête. Le deuxième span contient un bouton de validation qui sera désactivé par la fonction wp_nav_menu_menu_disabled_check si aucun élément n’est coché.
Enfin, l’élément span.spinner ajoute une icône d’animation.
La boîte de méta d’auteurs est complète, et nous pouvons apprécier le résultat de notre dur labeur dans l’image suivante.

La méta-boîte finale permettra à l'utilisateur admin d'ajouter des liens vers les archives de l'auteur.

La méta-boîte finale permettra à l’utilisateur admin d’ajouter des liens vers les archives de l’auteur.

Résumé

L’API du noyau WordPress de menu de navigation est un ensemble de fonctions de base qui créent des sections et des objets dans l’écran d’apparence des menus. Malheureusement, cette API n’est pas documentée dans le Codex, et la seule façon d’apprendre à modifier les fonctionnalités de l’écran des menus est une dissection approfondie du fichier /wp-admin/includes/nav-menu.php.
Même problème avec les modules d’éléments de menu. Comment sont-ils structurés ? Combien de typologies sont disponibles ? Peut-on créer de nouvelles typologies ? Aucune réponse à ces questions dans le Codex. Au moment d’écrire ces lignes, la seule façon de mieux comprendre les modules d’éléments est d’analyser le fichier du noyau /wp-admin/includes/nav-menu.php, et la fonction wp_setup_nav_menu_item (ligne 730 dans WordPress 4.5).
Pour ces raisons, cet article peut être considéré comme une première approche à ce sujet, et j’espère que vous les lecteurs laisserez vos suggestions et idées pour discussion dans les commentaires ci-dessous.

Le code complet de notre exemple d’extension WordPress de menu personnalisé est disponible dans un gist public.


Si vous avez aimé cet article, alors vous allez adorer la plateforme d'hébergement WordPress de Kinsta. Accélérez votre site Web et obtenez le support 24/7 de notre équipe de vétérans de WordPress. Notre infrastructure propulsée par Google Cloud met l’accent sur la mise à l’échelle automatique, la performance et la sécurité. Laissez-nous vous montrer la différence de Kinsta ! Découvrez nos plans