Accueil / Blog / Métier / 2015 / Gérer le fil d'Ariane Drupal par le code

Gérer le fil d'Ariane Drupal par le code

Par Sébastien Corbin publié 09/11/2015, édité le 12/11/2015
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.
Gérer le fil d'Ariane Drupal par le 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.

ABONNEZ-VOUS À LA NEWSLETTER !
Voir aussi
Varnish et Drupal 9 : le vidage de cache ciblé Varnish et Drupal 9 : le vidage de cache ciblé 31/12/2020

La mise en place d'un cache de pages anonymes Varnish devant un Drupal 9 permet une mise en place ...

Varnish et Drupal : gérer un cache anonyme étendu Varnish et Drupal : gérer un cache anonyme étendu 14/03/2018

Le rôle d'un Reverse Proxy Cache Varnish dans une architecture Web (type Drupal).

Migration d'un site Drupal 7 en Drupal 9 Migration d'un site Drupal 7 en Drupal 9 31/12/2020

Trucs, astuces et bouts de code pour migrer votre site web de Drupal 7 à Drupal 9

Sortie de Drupal 9 : préparez-vous ! Sortie de Drupal 9 : préparez-vous ! 28/05/2020

Dans quelques jours, le 3 juin 2020, aura lieu la sortie de Drupal 9 en version stable. À quels ...

Résolution de problèmes Drupal : construction de site (2/4) Résolution de problèmes Drupal : construction de site (2/4) 09/08/2013

Dans cette série d'articles, nous tentons de vous aider à vous sortir seuls de situations ...