Makina Blog
Gérer le fil d'Ariane Drupal par le code
Beaucoup de modules (Menu breadcrumb, Crumbs, Menu position, etc.) vous permettent de gérer le fil d'Ariane (breadcrumb) par l'interface. Voici comment simplifier tout cela par du code.
Les concepts de liens de menu, fil d'Ariane et l'arborescence actuelle (active trail) sont très entrelacés dans Drupal 7, et c'est réellement la croix et la bannière pour arriver au résultat voulu.
Si vous restez dans un principe où tout a un lien de menu dans la navigation (menu par défaut de Drupal), tout va bien. Mais si vous voulez par exemple faire en sorte que vos actualités aient pour parent votre liste d'actualités, ça se complique, voyons comment berner Drupal.
Travailler dans le bon hook
Très important, si vous souhaitez utiliser les fonctions telles que drupal_get_breadcrumb()
ou menu_get_active_trail()
dans votre code métier, il faudra copier le code dans un hook_init()
, si ce n'est pas le cas, alors vous pouvez travailler par exemple dans un hook_page_delivery_callback_alter()
uniquement quand lorsque la callback est 'drupal_deliver_html_page'
, cela permettra de ne pas exécuter le code pour les requêtes Ajax. De même, vous pouvez ajouter une condition telle que path_is_admin(current_path())
pour ne travailler que sur le front-end.
Travailler avec les bons menus
Nous allons beaucoup travailler avec menu_link_get_preferred()
, cette fonction un peu magique (autant pratique que très bizarre) est appelée pour récupérer le lien courant dans l'arborescence des menus.
Sachez que celle-ci recherche un lien de menu dans les menus systèmes (qui sont Menu principal, Navigation, Menu secondaire et Management), puis ensuite dans les menus personnalisés créés par vos soins. Cet ordre est modifiable en éditant la variable persistante 'menu_default_active_menus'
dans votre settings.php, le premier étant le plus à même de définir l'arborescence, par exemple :
$conf['menu_default_active_menus'] = [
'menu-menu-principal',
'menu-footer-1',
'menu-footer-2',
'management',
'main-menu',
];
Travailler avec les bonnes conditions
La mécanique est amenée à être très appelée, donc évitez de charger trop de données et d'exécuter des traitement trop lents, où la performance de votre site en pâtira. Essayer de rester dans les conditions simples telle que les types de contenu ou les vocabulaires.
Le code
Le point central de ce snippet se situe dans le deux dernières lignes, en polluant (dans le bon sens du terme) le cache statique de Drupal, lorsqu'il rappelera la fonction `menu_link_get_preferred()` pour construire l'active-trail ou le breadcrumb, son cache sera déjà rempli avec le lien de menu de notre parent.
Remplacez 'menu-menu-principal'
par le nom système de votre menu.
<?php
/**
* Implements hook_page_delivery_callback_alter().
*/
function fixtrail_page_delivery_callback_alter(&$callback) {
$current_path = current_path();
// Only work on normal pages, not ajax nor admin pages.
if ($callback != 'drupal_deliver_html_page' || path_is_admin($current_path)) {
return;
}
$parent_path = NULL;
// Set the nearest parent given certain conditions.
$item = menu_get_item();
if ($item['path'] == 'node/%') {
$node = $item['map'][1];
if ($node->type == 'evenement') {
$parent_path = 'evenements';
}
elseif ($node->type == 'dossier') {
$parent_path = 'dossiers';
}
elseif ($node->type == 'produit') {
$parent_path = 'produits';
}
}
elseif ($item['path'] == 'taxonomy/term/%') {
$term = $item['map'][2];
if ($term->vocabulary_machine_name == 'lexique') {
$parent_path = 'lexique';
}
}
// If parent found, set it for menu tree trail future build.
if ($parent_path) {
menu_tree_set_path('menu-menu-principal', $parent_path);
menu_link_get_preferred($parent_path);
// Fool drupal so that it take the correct link to build the breadcrumb.
$preferred_links = &drupal_static('menu_link_get_preferred');
$preferred_links[$current_path] = $preferred_links[$parent_path];
}
}
/**
* Implements hook_menu_breadcrumb_alter().
*/
function fixtrail_menu_breadcrumb_alter(&$active_trail, $item) {
// Add the current page to the breadcrumb, if not already done.
$end = end($active_trail);
if (current_path() != $end['href']) {
$active_trail[] = $item;
}
}
Pour aller plus loin
Si ce tutorial vous a plu, n'hésitez pas à consulter nos autres billets de blog Drupal et notre formation Drupal développeur.
Formations associées
Actualités en lien
Migration d'un site Drupal 7 en Drupal 11
Trucs, astuces et "bouts" de code pour migrer votre site web de Drupal 7 à Drupal 11. Compte-rendu d'une conférence donnée au Drupalcamp Rennes 2024.
Makina Corpus, partenaire du DrupalCamp 2024
Nous sommes fiers d’annoncer que Makina Corpus est le sponsor du DrupalCamp à Rennes. Notre expert vous y propose une conférence « migrer de Drupal 7 à Drupal 10 ».