Dans cette première partie nous allons voir comment mettre en place un menu accessible simple, sans sous-menu : récapitulatif des bases, explications des notions importantes et des moyens pour rendre notre menu à un niveau accessible. C’est parti !
Créer un menu dans WordPress : les bases
Tout d’abord voyons en quelques étapes comment mettre en place un menu sur WordPress.
1) Enregistrer un emplacement de menu
Dans le fichier de configuration du thème (souvent functions.php
ou un sous-fichier si vous prônez l’organisation comme chez Alsacréations) enregistrons un menu "Menu principal" avec la fonction register_nav_menu()
. Il a pour slug main-menu
qui nous sera utile pour afficher le menu :
function register_my_menu() {
register_nav_menu( 'main-menu' => __( 'Menu principal', 'text-domain' ) );
}
add_action( 'after_setup_theme', 'register_my_menu' );
Dans l’administration WordPress, l’emplacement apparait dans les réglages du menu :
2) Afficher le menu
Il n’y a plus qu’à appeler le menu là où nous souhaitons l’afficher, dans l’en-tête header.php
par exemple.
Pour cela il faut utiliser la fonction wp_nav_menu()
et préciser le slug précédemment enregistré :
/**
* Affiche le menu "Menu principal" enregistré au préalable.
*/
wp_nav_menu([
'theme_location' => 'main-menu',
]);
Cette fonction propose des options de configuration très avancées. Vous retrouverez la liste des paramètres disponibles sur la documentation officielle de wp_nav_menu
.
3) Administrer le menu
Pour le moment nous souhaitons créer un menu simple. Pour cela créer un nouveau menu dans l'interface d'administration de WordPress, le nommer, et cocher l’emplacement enregistré à l’étape 1.
Si vous avez bien suivi les étapes, vous devriez avoir un menu qui fonctionne à minima. Et voici le code généré par WordPress :
<div class="menu-menu-principal-container">
<ul id="menu-menu-principal" class="menu">
<li id="menu-item-256" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-home current-menu-item page_item page-item-251 current_page_item menu-item-256">
<a href="">Accueil</a>
</li>
<li id="menu-item-290" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-290">
<a href="">Actualités</a>
</li>
<li id="menu-item-253" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-253">
<a href="">Contact</a>
</li>
</ul>
</div>
Rendre notre menu accessible
Côté accessibilité, le code généré possède quelques points à améliorer :
- le conteneur du menu n’a pas de sémantique. C’est une simple
<div>
. - La page courante n’est pas restituée aux lecteurs d’écran.
Mais comment corriger cela ? La fonction wp_nav_menu()
possède des paramètres qui pourront nous aider, mais cela ne nous permettra pas de tout corriger. Dans ce cas, il faudra modifier le code généré par WordPress.
Comment WordPress gère ce code ? Comment modifier ce code ?
Nous allons utiliser le walker Walker_Nav_Menu
qui nous sera utile pour personnaliser le code généré. Mais avant, explications !
Qu’est ce qu’un Walker ?
Un walker est une classe abstraite PHP qui permet de parcourir une arborescence de données (objets ou tableaux) afin de générer du code HTML.
Par rapport à notre menu ➡️ le walker va parcourir le menu, et exécuter à chaque noeud une fonction.
Quand nous observons la classe dans le codex, le walker possède 4 fonctions :
start_lvl
: correspond au début d’un sous-menu<ul>
et son contenu.end_lvl
: Fin d’un sous-menu</ul>
.start_el
: Début d’un élément du menu. Équivalent du<li>
et son contenu.end_el
: Fin d’un élément</li>
.
Et l’avantage d’un walker, c’est qu’il est possible de l’étendre afin de customiser ces fonctions. Spoiler : c’est ce que nous allons faire 🤠.
Rendre notre menu sémantiquement parlant
Actuellement, notre menu est perçu simplement comme une liste, avec un conteneur ne donnant aucun contexte.
Nous allons donc ajouter un peu de sémantique pour restituer, à l’utilisateur et aux lecteurs d’écran, que c’est un menu de navigation. Pour cela, faisons appel aux landmarks ARIA.
Rappel : les landmarks permettent de déclarer des régions (header
, main
, footer
, nav
, aside
, etc.) afin de structurer une page et de restituer le contexte aux lecteurs d’écran.
Ici, nous allons englober notre menu d’une balise <nav>
avec un attribut ARIA role="navigation"
. Si plusieurs menus de navigation existent dans le site, une bonne pratique est de l’identifier via un attribut aria-label
ou la combinaison aria-labelledby/id
.
Si vous avez regardé en détail le codex de wp_nav_menu()
, vous vous demanderez sûrement pourquoi ne pas utiliser les paramètres container
et container_aria_label
. Comme ils sont de type string
, il n’aurait donc pas été possible de passer l’attribut role="navigation"
.
Nous privilégions donc de ne pas utiliser le conteneur généré par WP :
<nav role="navigation" aria-label="<?php _e('Menu principal', 'text-domain'); ?>">
<?php
wp_nav_menu([
'theme_location' => 'main-menu',
'container' => false // On retire le conteneur généré par WP
]);
?>
</nav>
Préciser la page courante
Visuellement la page courante d’un menu peut-être indiquée par la couleur, la forme (bordure basse), une icône, etc. :
Mais qu’en-est-il des personnes malvoyantes utilisant un lecteur d’écran ? Il faut une alternative HTML en plus de l’indication visuelle.
L’attribut aria-current
rentre en piste ! Il permet d’indiquer aux lecteurs d’écran l’élément actif parmi un ensemble. Dans notre cas, il aura pour valeur :
page
sur la page courante;true
sur la page parente, si existante.
Exemples :
<a href="#" aria-current="page">Accueil</a>
<a href="#" aria-current="true">Actualités</a>
<ul class="sub-menu">
<li>
<a href="#" aria-current="page">Sous-actualité</a>
</li>
<li>
<a href="#">Sous-actualité</a>
</li>
</ul>
Mais.. comment faire sur WordPress ? Si vous avez bien suivi c’est le moment d’étendre le walker 🚀
Étendre le walker par défaut
Pour cela, nous allons dans un premier temps créer un nouveau fichier menus.php
et l’appeler dans le fichier functions.php
.
Dans ce fichier nous allons simplement copier/coller le walker existant de WordPress Walker_Nav_Menu.
Quel est l’intérêt me direz-vous ? Simplement pour éviter de faire des erreurs. Nous aurons juste à customiser la/les fonction(s) souhaitée(s).
La seconde étape est de renommer le walker pour le distinguer d’autres potentiels walkers :
class A11y_Walker_Nav_Menu extends Walker {
Ensuite, nous allons appeler ce walker dans la fonction wp_nav_menu()
en ajoutant un paramètre walker
pour créer une instance de notre classe A11y_Walker_Nav_Menu
:
<nav role="navigation" aria-label="<?php _e('Menu principal', 'text-domain'); ?>">
<?php
wp_nav_menu([
'theme_location' => 'main-menu',
'container' => false,
'walker' => new A11y_Walker_Nav_Menu()
]);
?>
</nav>
Personnaliser notre nouveau walker
Notre objectif est d’ajouter un attribut aria-current
sur un élément du menu lorsqu’il correspond à la page courante.
Comme précisé plus haut, c’est la fonction start_el()
qui va permettre de modifier le contenu d’un élément du menu.
Avant tout, regardons plus en détail cette fonction :
/**
* Starts the element output.
*
* @since 3.0.0
* @since 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
* @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id`
* to match parent class for PHP 8 named parameter support.
*
* @see Walker::start_el()
*
* @param string $output Used to append additional content (passed by reference).
* @param WP_Post $data_object Menu item data object.
* @param int $depth Depth of menu item. Used for padding.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $current_object_id Optional. ID of the current menu item. Default 0.
*/
public function start_el( &$output, $data_object, $depth = 0, $args = null, $current_object_id = 0 ) {
// Restores the more descriptive, specific name for use within this method.
$menu_item = $data_object;
// Suite de la fonction...
Les commentaires nous précisent que :
- le paramètre
$output
est le résultat de la fonction sous forme de contenu HTML. - Le paramètre
$data_object
est un objet qui nous permet de récupérer toutes les informations de l’élément. À noter que la première ligne de la fonction nous précise d’utiliser$menu_item
. Cette variable regroupe plusieurs clés (n’hésitez pas à explorer son contenu en utilisantvar_dump($menu_item)
).
Arrêtons-nous sur la clé current
. C’est un booléen qui a pour valeur true
lorsque l’élément correspond à la page courante. Parfait, c’est ce que nous voulons !
Mais comment ajouter un attribut à l’élément ? Et bien WordPress ne fait pas les choses à moitié : si vous regardez bien la fonction, un paramètre $atts
est mis à disposition. Il utilise le filtre nav_menu_link_attributes
:
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $menu_item, $args, $depth );
Ce filtre permet d’ajouter/modifier des attributs à l’élément actuel. Il faut donc ajouter, avant la ligne ci-dessus, le code suivant :
$atts['aria-current'] = $menu_item->current ? 'page' : '';
Et voilà, l’attribut est ajouté dans le code lorsque $menu_item
possède la clé current
. Plutôt simple, hein ?
Ajouter un attribut title
si le lien s’ouvre dans un nouvel onglet
L’utilisation d’un attribut title
permet d’ajouter un complément d’information. Attention à l’utiliser correctement : il faut reprendre l’intitulé du lien, puis ajouter le texte complémentaire (notes du glossaire RGAA).
Dans notre cas nous allons préciser qu’un lien s’ouvre dans un nouvel onglet lorsque son target
vaut _blank
:
Exemple :
<a href="#" target="_blank" title="Intitulé du lien (s'ouvre dans un nouvel onglet)">Intitulé du lien</a>
Préciser cette action permet de prévenir les utilisateurs d’un changement brusque et éviter de perturber leur navigation.
Comment le faire sur WordPress ?
Nous allons donc modifier la fonction start_el()
pour ajouter un title
lorsque le target
est _blank
. Si vous regardez bien, cette condition existe déjà :
if ( '_blank' === $menu_item->target && empty( $menu_item->xfn ) )
Il n’y a plus qu’à ajouter l’attribut title
et lui donner pour valeur le titre de l’élément title
suivi de notre texte :
if ( '_blank' === $menu_item->target && empty( $menu_item->xfn ) ) {
// Attribut title : on précise que le lien s'ouvre dans un nouvel onglet
$atts['title'] = $menu_item->title . __( ' (s\'ouvre dans un nouvel onglet)', 'text-domain' );
}
Voilà ce qu’il en est pour la mise en place d’un menu accessible simple. Cette première partie était assez longue car nous trouvions important de revenir sur les bases de la création d’un menu WordPress. La prochaine entrera directement dans le vif du sujet et concernera la gestion des sous-éléments d’un menu.
Commentaires
Et la touche 'esc' pour refermer le menu ?
Merci @Alyssa!
Ton tuto m'est très utile. Je reviens sur Wordpress après presqu'une décennie d'absence.
Je dois me remettre un peu à jour, il y a eu quelques changements, et surtout, j'ai oublié beaucoup de choses.
^^