Ajouter une section à la barre d'outils de Drupal

Dans cet article

Lors de l'installation d'un site Drupal avec le profil standard, un module core est activé par défaut nommé Toolbar. Ce module fournit une barre d'administration qui s'affiche en haut de site.

Il est possible (et même indispensable) de rendre cette bar d'outil déroulante pour accéder aisément aux sous-menus pour configurer Drupal. Pour cela, le module Admin Toolbar est un incontournable. A tel point que l'on parle de l'inclure dans Drupal core.
Barre d'outils Drupal
La barre d'outils (toolbar) de Drupal, avec les modules Admin Toolbar, Devel et Webform d'activés

Cette barre d'outils se décompose en deux parties: une première zone horizontale noire en haut, dont les éléments sont appelés des onglets (tabs). A chaque tab est associé un tray sous la forme d'une seconde barre, grise cette fois, qui peut être affichée horizontalement en haut de page ou verticalement sur le côté gauche de l'écran.

Il est possible d'ajouter des éléments dans chacune de ces sections:

  • en ajoutant un élément dans un tray existant, comme le module Webform sur l'image, ou comme le fait aussi le module Drupal Commerce qui s'ajoutent dans l'onglet Gérer
  • en créant complètement un nouveau tab avec ou sans un tray associé, comme le fait le module Devel sur l'image au-dessus

Nous allons dans la suite démontrer les deux méthodes, en commençant par l'ajout d'une lien type Webform sur l'image, dans le tray d'administration par défaut de Drupal.

Ajout d'un élément de menu via l'interface

Ajout au menu administrateur
Ajout au menu administrateur sous le parent "Administration"

Le tray par défaut associé à l'onglet Gérer est celui dans lequel on retrouve les sections d'administration classiques de Drupal: Contenu, Structure, Apparence, etc... La première chose à comprendre, c'est que les éléments à cet ne sont autres que les éléments du menus "Administration" (admin) que l'on peut retrouver à la page /admin/structure/menu/manage/admin.

Pour ajouter un élément dans ce menu et à cet endroit, il suffit donc de:

  • Se rendre sur la page d'administration du menu admin :
    /admin/structure/menu/manage/admin
  • Cliquer sur le lien "Ajouter un lien" en haut de page :
    /admin/structure/menu/manage/admin/add
  • Créer votre lien classiquement en choisissant pour parent "Administration" dans l'onglet déroulant

C'est tout ! Votre nouveau lien est désormais présent dans la Toolbar.

Ajout d'un élément par la programmation

L'ajout d'un élément dans le tray de l'onglet Gérer peut se faire par la programmation. C'est ainsi que votre module custom, à l'image de Webform ou Commerce, peut s'insérer à cet endroit.

Maintenant que nous avons vu qu'un lien à cet endroit n'est rien d'autre qu'un élément de menu. Il suffit de se reporter à n'importe quel tutoriel pour ajouter un lien de menu via Drupal. Par soucis de complétude, j'en donne ici le code.

Il convient d'ajouter ces lignes au fichier monmodule.links.menu.yml.

1
2
3
4
5
6
monmodule.monlien:
  title: 'Mon lien'
  route_name: nimporte.quelle.route
  parent: system.admin
  description: 'La description de mon lien'
  weight: -9

La première ligne est le nom machine de votre lien. route_name fait référence à la route vers laquelle pointe le lien que l'on est entrain de créer. Cela peut-être n'importe quelle route, créé par votre module, par Drupal ou par un autre module. parent fait ici obligatoirement à system.admin puisque c'est le nom machine correspondant au lien "Administration" dont nous avons parlé dans le paragraphe précédent. Enfin le poids weight est optionnel et permet de placer le lien dans l'ordre souhaité par rapport aux autres.

La toolbar de Drupal avec notre nouvelle section
Nouveau lien "Gifty" avec son icône associée

Dans mon article sur le défi Gitfy, j'ai créé en partie 3 le lien Gifty avec une jolie icône associée. L'ajout de cette icône est un peu plus intéressante.

Organisation des pictos dans le dossier du thème
Organisation des pictos dans le dossier du module

Toolbar utilise classiquement un jeu de deux couleurs pour ses icônes: gris (#787878) et noir (#000000) suivant si le lien est au-repos, au survol ou actif. Il faudra donc deux icônes correspondant à ces deux couleurs. Cela peut-être un picto PNG qui devra alors être de taille 20x20 pixels ou et c'est cce qui est recommandé, un picto au format SVG.

Vous pouvez trouver des pictos SVG appropriés et librement utilisables dans des librairies d'icônes en ligne, par exemple sur FontAwesome est l'une d'elle.

Sans que ce soit obligatoire, il est de tradition de placer ces icônes dans votre thème ou votre module custom dans un dossier icons subdivisé en dossier du nom de la couleur des pictos.

Ces deux icônes vont maintenant devoir être ajoutée au pseudo élément before d'un sélecteur bien particulier de la barre d'outil. Le css associé sera placé dans un fichier css/monmodule.icons.css et ressemblera à ceci:

1
2
3
4
5
6
7
8
/* Tray styling (second row) */
.toolbar-tray .toolbar-icon.toolbar-icon-monmodule-monlien:before {
  background-image: url("../icons/787878/gift.svg");
}
.toolbar-tray .toolbar-icon.toolbar-icon-monmodule-monlien:active:before,
.toolbar-tray .toolbar-icon.toolbar-icon-monmodule-monlien.is-active:before {
  background-image: url("../icons/000000/gift.svg");
}
Remarquez dans le nom du lien la partie monmodule-monlien. C'est le nom machine que l'on avait choisi pour le lien dans lequel tous les caractères autres qu'alphabétiques ont été transformés en tiret.

Il ne reste plus qu'à attacher ce CSS à la barre d'outil pour qu'il soit chargé en même temps que celle-ci. Rien de plus simple. Comme à chaque fois que l'on parle de CSS dans Drupal, il faut commencer à l'incorporer dans une libraire Drupal. Pour cela, nous créons le fichier monmodule.libraries.yml contenant:

1
2
3
4
5
toolbar:
  version: VERSION
  css:
    theme:
      css/monmodule.icons.css: {}

Le lien entre l'usage de cette librairie et le chargement de la barre d'outil se fait au moyen du hook_toolbar_alter qui est déclaré dans le fichier monmodule.module via les lignes de code suivantes:

1
2
3
4
5
6
/**
 * Implements hook_toolbar_alter().
 */
function monmodule_toolbar_alter(&$items) {
  $items['administration']['#attached']['library'][] = 'monmodule/toolbar';
}

C'est tout ! Si vous avez l'habitude de manipuler les librairies Drupal et que vous savez quel hook utiliser, l'ensemble vous aura pris 5 minutes tout au plus.

Ajouter un onglet et sa section

Nous en avons parlé en début d'article, il est également possible d'insérer un onglet dans la partie supérieure de la barre d'outil. C'est forcément un peu plus complexe, mais pas tant que cela: il suffit d'utiliser un hook nommé hook_toolbar et d'y ajouter le render array adapté en utilisant form API.

Afin de garder un exemple simple, nous allons montrer ici comment ajouter un lien "Main navigation menu" qui affichera le menu de navigation principal de ce site dans le tray. Comme d'habitude, le hook s'ajoute à notre fichier monmodule.module.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * Implements hook_toolbar().
 */
function monmodule_toolbar() {
  return [
    'main' => [
      '#type' => 'toolbar_item',
      '#weight' => 999,
      'tab' => [
        '#type' => 'link',
        '#title' => t('Main navigation menu'),
        '#url' => \Drupal\Core\Url::fromRoute('<none>'),
        '#attributes' => [
          'title' => t('Main navigation menu'),
          'class' => ['toolbar-icon', 'toolbar-icon-main-menu'],
        ],
      ],
      'tray' => [
        '#heading' => t('Main navigation menu'),
        'menu' => _monmodule_build_main_menu()
      ],
      '#attached' => [
        'library' => 'monmodule/toolbar',
      ],
    ]
  ];
)

Nous remarquons que l'élément de niveau principal est de type toolbar_item, un type définit par le module toolbar. Cet élément contient nécessairement un enfant dont la clef est 'tab' et optionnellement, un autre nommé 'tray'. Ceux-ci sont créer via form API de façon classique, nous avons donc créer un lien pour l'onglet tab et un menu pour le tray. Ce menu est crée via une fonction helper dont voici la définition:

1
2
3
4
5
6
7
8
9
10
11
12
13
function _monmodule_build_main_menu() {
  $menu_tree = \Drupal::service('toolbar.menu_tree');
  $parameters = new MenuTreeParameters();
  $parameters->setMinDepth(0)->setMaxDepth(4)->onlyEnabledLinks();
  $tree = $menu_tree->load('main', $parameters);
  $manipulators = [
    ['callable' => 'menu.default_tree_manipulators:checkAccess'],
    ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
    ['callable' => 'toolbar_menu_navigation_links'],
  ];
  $tree = $menu_tree->transform($tree, $manipulators);
  return $menu_tree->build($tree);
}

Le but n'étant pas ici de faire un article sur la génération de menu, j'indiquerais seulement que le service menu_tree est remplacé ici par le service toolbar.menu_tree qui va rajouter divers classes et attributs pour un design consistant. De même fait le transformateur de menu toolbar_menu_navigation_links.

Dans le cadre d'un projet réel, notre fonction helper est correcte, mais un peu faible d'un point de vue performance. Je conseillerais vivement pour un site professionnel de passer par un lazyBuilder.

On remarquera que nous avons attaché la librairie Drupal que nous avions créé au paragraphe précédent. Les menus du tray peuvent être agrémentés d'icônes de cette manière.

De façon similaire, notre onglet peut lui aussi recevoir une icône. Par convention, deux couleurs sont nécessaires: blanc (#FFFFFF) et gris clair (#BEBEBE). Le CSS correspondant ressemblera ici alors ceci:

1
2
3
4
5
6
7
8
/* Toolbar styling (first row). */
.toolbar-bar .toolbar-icon-main-menu:before {
    background-image: url("../icons/bebebe/compass.svg");
}
.toolbar-bar .toolbar-icon-main-menu:active:before,
.toolbar-bar .toolbar-icon-main-menu.is-active:before {
    background-image: url("../icons/ffffff/compass.svg");
}
Toolbar avec un nouvel onglet actif affichant le menu principal du site
Le menu principal de ce site apparaît désormais dans la barre d'outils.

Ajouter un commentaire

Votre nom sera affiché publiquement avec votre commentaire.
Votre email restera privé et n'est utilisé que pour vous notifier de l'approbation de ce commentaire.
Sur internet, vous pouvez être qui vous voulez. Soyez quelqu'un de bien :)