Créer un fil d'Ariane totalement personnalisé en Drupal 8

La documentation Drupal 6 n'est plus maintenue et en cours de dépublication.

Présent sur la plupart des sites, le fil d'Ariane ou breadcrumb permet d'aider l'internaute durant sa navigation en lui donnant sa localisation précise, et lui fournit via des liens l'occasion de revenir sur ses pas ou d'accéder à des pages plus générales (une page de catégorie par exemple).

Un CMS comme Drupal est capable d'automatiser la génération de fils d'Ariane : des modules de la communauté tels qu'Easy Breadcrumb qui permet de déduire la breadcrumb d'un contenu de son URL, ou Menu Breadcrumb qui génère la breadcrumb d'un contenu à partir du menu auquel il est rattaché, permettent de remplir les cas simples. Mais dans le cas d'un besoin plus poussé, un peu de code est nécessaire...

Drupal 8 possède une API riche et qui pousse à l'orienté objet : pour tisser finement un fil d'Ariane, il faut commencer par créer une classe dont le fichier sera placé dans le dossier src/Breadcrumb d'un module. Par exemple imaginons qu'on veuille implémenter une breadcrumb spécifique aux contenus de type Article : créons une classe ArticleBreadcrumbBuilder qui sera contenue dans le fichier ArticleBreadcrumbBuilder.php. Cette classe devra implémenter l'interface BreadcrumbBuilderInterface (dont les méthodes ont un objet implémentant RouteMatchInterface en paramètre) et utilisera les classe Breadcrumb et Link pour générer le fil d'ariane proprement dit, on aura donc les bases suivantes dans notre fichier :

<?php

namespace Drupal\module_name\Breadcrumb;

use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Link;

class ArticleBreadcrumbBuilder implements BreadcrumbBuilderInterface {

}

Il reste à écrire les méthodes exigées par l'interface : d'après la documentation il s'agit de la méthode applies(), qui permet de définir dans quels cas appeler ce constructeur de fil d'Ariane, et de la méthode build() qui doit retourner un objet de la classe Breadcrumb.
Commençons par écrire le code de applies() :

    public function applies(RouteMatchInterface $route_match) {

        $parameters = $attributes->getParameters()->all();
        if(isset($parameters['node']))
            return $parameters['node']->getType() === 'article';

    }

Cette méthode renverra la valeur TRUE si la page affichée correspond à un nœud et qu'il est de type article. Reste à définir le contenu du fil d'Ariane, disons un lien vers l'accueil, un texte "Articles" sans lien - pour l'exemple - et le titre de l'article, en mettant le tout en cache pour chaque URL via la méthode addCacheContexts() :

    public function build(RouteMatchInterface $route_match) {

        $breadcrumb = new Breadcrumb();

        $breadcrumb->addCacheContexts(["url"]);

        $breadcrumb->addLink(Link::createFromRoute(t('Home'), '<front>'));

        $breadcrumb->addLink(Link::createFromRoute(t('Articles'), '<none>'));

        $request = \Drupal::request();
        $route_match = \Drupal::routeMatch();
        $page_title = \Drupal::service('title_resolver')->getTitle($request, $route_match->getRouteObject());
        if (!empty($page_title)) {
            $breadcrumb->addLink(Link::createFromRoute($page_title, '<none>'));
        }

        return $breadcrumb;
    }

Ainsi le code de notre classe est complet ! Il reste à la déclarer comme service dans le fichier module_name.services.yml en utilisant le tag breadcrumb_builder afin de connecter notre classe au gestionnaire de breadcrumb de Drupal et en précisant également la priorité de notre bâtisseur de fil d'Ariane par rapport aux autres (ceux qui sont moins prioritaires seront ignorés) :

services:
  module_name.articles_breadcrumb:
    class: Drupal\module_name\Breadcrumb\ArticleBreadcrumbBuilder
    tags:
      - { name: breadcrumb_builder, priority: 100 }

Et voilà, après avoir vidé le cache (et éventuellement augmenté la valeur du tag priority si un autre module agissant sur les breadcrumbs est doté d'une priorité supérieure, par exemple Easy Breadcrumb dont la priorité est de 1003), vos articles devraient présenter votre breadcrumb customisée !

Version de Drupal :