Créer un mega menu avec Drupal 8

Un navire ancien à trois mats

Créer un mega menu responsive est souvent un pré-requis régulier sur tout projet, Drupal 8 ou autre. Et si nous pouvons trouver quelques solutions proposant de créer des mega menus facilement, très souvent, ces solutions restent assez rigides et peuvent difficilement être adaptées aux pré-requis d'un projet. Mais qu'est-ce qu'un mega menu ? Ce n'est ni plus ni moins qu'un menu qui contient un peu plus qu'une liste de liens (proposées par le système de menu de Drupal 8), avec des liens spécifiques, du texte, des images, etc.

Plutôt qu'une solution rigide, qui peut convenir si nous sommes prêts à nous plier à ses exigences, nous pouvons aussi utiliser une solution plus souple, ouverte mais qui demande aussi un peu plus de travail au niveau du theming. Découvrons comment construire un mega menu avec le module Simple Mega Menu.

Fonctionnement général

L'idée principale de ce module repose sur deux postulats :

  • Un mega menu peut être conçu en utilisant toute la puissance de la Field API de Drupal 8, en fait de la même manière que nous concevons différents types de contenu en leur adjoignant différents types de champ.
  • Le rendu final est délégué au moteur de template Twig, laissant une grande marge de manoeuvre pour le positionnement des différents éléments d'un mega menu.

Simple mega menu n'est donc pas une solution out of the box qui va vous fournir un mega menu immédiatement utilisable (quoi qu'il propose un exemple de mega menu pré-configuré si on active le module exemple). Il permet tout simplement d'utiliser une entité de contenu comme support pour son mega menu, et donc de pouvoir utiliser tout type de champ ; que ce soit des liens, des références vers des contenus, des images, des vidéos, du texte, des widgets embarqués, des vues, etc. Bref, tout ce que vous pouvez faire avec les types de contenus de drupal.

Pour le rendu du mega menu, le module fournit deux fonctions Twig :

  • has_megamenu(item.url) : permet de savoir si un lien de menu dispose d'un mega menu qui lui est attaché
  • view_megamenu(item.url, view_mode) : permet de d'afficher le mega menu dans le mode d'affichage spécifié

Avec ces 2 fonctions Twig, vous êtes alors en mesure d'afficher un mega menu sous quelque forme que ce soit, mise en forme configurée depuis le template twig de l'entité mega menu (ou encore depuis l'interface graphique), à l'endroit exact où vous souhaitez positionner votre mega menu par rapport au lien de menu (et ses enfants éventuels).

Découvrons plus en détails le fonctionnement de Simple Mega Menu.

Création d'un type de mega menu

Une fois le module installé, nous devons créer un type de mega menu disponible dans le menu d'administration Structure, à l'url /admin/structure/simple_mega_menu_type.

Add mega menu type

Nous créons un type de mega menu et nous sélectionnons pour quels menus les contenus de ce type de mega menu seront disponibles.

Create mega menu type

 

Une fois le type de mega menu enregistré nous pouvons alors gérer, comme n'importe quel type de contenu, les différents champs qui vont le composer, ses modes d'affichages, etc.

Add fields to mega menu

 

Ici nous avons ajouté un certain nombre de champs

  • Links: un champ multiple de type Lien
  • Image : un champ de type Image
  • Text : un champ de type Text long
  • Bottom links : un autre champ multiple de type Lien

Add fields to mega menu

 

Nous configurons alors les différents modes d'affichage de notre entité. Par défaut, le module installe deux modes d'affichage intitulé Before et After. Vous pouvez bien sûr les supprimer, ou en ajouter autant que vous le souhaitez.

Ici, nous configurons les champs Image et Text pour être affiché dans ce mode d'affichage.

Mega menu view mode before configuration

 

Et le mode d'affichage After est quant à lui configuré pour n'afficher que les liens du champ Link

Mega menu view mode after configuration

 

Pour ajouter et configurer d'autres modes d'affichage, il nous suffit d'aller sur l'url (/admin/structure/display-modes/view) de configuration des modes d'affichages et d'en ajouter un nouveau.

Mega menu add new view mode

Pour rester simple dans ce tutoriel, nous n'ajouterons pas le mode d'affichage Bottom, que nous devrions configurer pour nous permettre d'afficher uniquement le champ Bottom Links. Mais je pense que vous avez compris le principe. 

Après ces quelques opérations de configuration, strictement similaires à la gestion des types de contenu, nous disposons d'un type de mega menu qui va nous permettre de créer nos contenus et associer ces contenus à des éléments du (ou des) menu cible sélectionné lors de sa création.

Il ne faudra pas oublier aussi de configurer les permissions, pour permettre aux visiteurs ou utilisateurs de votre site de visualiser les entités de mega menu créées.

Mega menu configuration permissions

Création des contenus du mega menu

Nous pouvons accéder depuis le menu Contenu > Simple mega menu list à la liste des mega menus créés.

Liste des mega menus

 

Et nous pouvons bien sûr en créer autant que de besoin en utilisant le bouton adéquat.

Création d'un élément de mega menu

 

Et notre premier contenu de notre mega menu est créé.

Premier élément du mega menu

 

Association des éléments du mega menu au liens du menu

Pour afficher notre premier contenu de mega menu, il nous faut le sélectionner sur le lien du menu pour lequel nous souhaitons afficher ce mega menu. Pour ce faire un nouveau champ est disponible dans le formulaire de création d'un lien de menu. Sélectionner le mega menu créé précédemment depuis le champ Simple Mega menu (champ à auto-complétion).

Association mega menu to menu link

 

Et voilà c'est fini, ou presque. Vous pouvez répétez autant que de besoin sur les différents liens de votre menu l'opération. Assurez vous également que le bloc de votre menu est configuré correctement pour afficher une profondeur suffisante de votre menu.

Menu bloc configuration

 

Par défaut, dans le template Twig proposé par le module, les mega menu attachés aux liens ne seront affichés que si ce lien dispose de liens enfants. Assurez donc de disposer de quelques liens enfants sur votre lien de menu principale.

Menu hierarchy

Si vous n'avez pas ou ne souhaitez pas de liens enfants, qu'à cela ne tienne, il vous suffit alors juste de modifier le template Twig par défaut en le copiant dans votre thème, et de modifier quelques lignes.

Personnalisation du mega menu avec Twig

Le module Simple Mega Menu propose un template par défaut pour la construction des menus, notamment les menus qui sont ciblés par un type de mega menu. Ce template est juste une surcharge du template Twig par défaut inclus avec Drupal 8, sur lequel quelques lignes ont été ajoutées, ces quelques lignes qui vont vous permettre d'injecter chaque partie de vos mega menu à un endroit très précis de la structure HTML de votre menu.

Découvrons ce template

{% import _self as menus %}

{#
  We call a macro which calls itself to render the full tree.
  @see http://twig.sensiolabs.org/doc/tags/macro.html
#}
{{ attach_library('simple_megamenu/base') }}
{{ menus.menu_links(items, attributes, 0) }}

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    {% if menu_level == 0 %}
      <ul{{ attributes.addClass('menu', 'menu--simple-mega-menu') }}>
    {% else %}
      <ul {{ attributes.removeClass('menu--simple-mega-menu') }}>
    {% endif %}
    {% for item in items %}
      {%
        set classes = [
          'menu-item',
          item.is_expanded ? 'menu-item--expanded',
          item.is_collapsed ? 'menu-item--collapsed',
          item.in_active_trail ? 'menu-item--active-trail',
        ]
      %}
      <li{{ item.attributes.addClass(classes) }}>
        {{ link(item.title, item.url) }}
        {% if item.below %}
          {% if has_megamenu(item.url) %}
            <div class="mega-menu-wrapper">
              <div class="mega-menu-background"></div>
              {{ view_megamenu(item.url, 'before') }}
              {{ menus.menu_links(item.below, attributes.addClass('mega-menu-item'), menu_level + 1) }}
              {{ view_megamenu(item.url, 'after') }}
            </div>
          {% else %}
            {{ menus.menu_links(item.below, attributes.removeClass('mega-menu-item'), menu_level + 1) }}
          {% endif %}
        {% endif %}
      </li>
    {% endfor %}
    </ul>
  {% endif %}
{% endmacro %}

 

La partie la plus significative de ce template est bien sûr là où est rendu le mega menu.

<li{{ item.attributes.addClass(classes) }}>
  {{ link(item.title, item.url) }}
  {% if item.below %}
    {% if has_megamenu(item.url) %}
      <div class="mega-menu-wrapper">
        <div class="mega-menu-background"></div>
        {{ view_megamenu(item.url, 'before') }}
        {{ menus.menu_links(item.below, attributes.addClass('mega-menu-item'), menu_level + 1) }}
        {{ view_megamenu(item.url, 'after') }}
      </div>
    {% else %}
      {{ menus.menu_links(item.below, attributes.removeClass('mega-menu-item'), menu_level + 1) }}
    {% endif %}
  {% endif %}
</li>

En utilisant la fonction has_megamenu(), nous pouvons tester si le lien dispose d'un mega menu qui lui est attaché, en utilisant la fonction view_mega_menu() nous pouvons afficher notre mega menu dans n'importe quel mode d'affichage. Et nous disposons d'une liberté totale pour positionner selon nos besoins notre mega menu.

Par exemple vos liens de menu principaux n'ont pas de liens enfants mais juste un mega menu. Modifiez cette portion de code ainsi et l'affaire est réglée.

<li{{ item.attributes.addClass(classes) }}>
  {{ link(item.title, item.url) }}
  {% if has_megamenu(item.url) %}
    <div class="mega-menu-wrapper">
      <div class="mega-menu-background"></div>
      {{ view_megamenu(item.url, 'before') }}
      {{ view_megamenu(item.url, 'after') }}
    </div>
  {%endif %}
  {% if item.below %}
    {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
  {% endif %}
</li>

Vous avez besoin d'une classe spécifique pour vos liens principaux contenant un mega menu ? Ajoutez juste une classe supplémentaire

{%
  set classes = [
    'menu-item',
    item.is_expanded ? 'menu-item--expanded',
    item.is_collapsed ? 'menu-item--collapsed',
    item.in_active_trail ? 'menu-item--active-trail',
    has_megamenu(item.url) ? menu-item--megamenu,
  ]
%}

Les mega menus à portée de Twig

Ce module ne nous propose pas de solution packagée, à portée de clic, juste à portée de Twig. Mais personnellement je crois n'avoir jamais pu utiliser une telle solution, tant les contraintes sont souvent multiples. Et comme la solution apportée par ce module se limite à juste faire le nécessaire, à savoir insérer du balisage HTML particulier au sein d'une liste de liens de menu classiques, celle-ci reste compatible avec tout autre module intervenant sur le système de menu, modules pouvant vous proposer des menus responsives comme par exemple le module Responsive and off-canvas menu.

Ce module nous permet ainsi d'offrir une interface graphique aux webmestres pour mettre à jour les éléments du mega menu, en s'appuyant principalement sur le coeur de Drupal 8 et ses entités, tout en permettant à un développeur Drupal (ou un intégrateur connaissant Twig) de positionner précisément ces différents éléments, pour pouvoir obtenir en quelques heures un mega menu complètement maîtrisé. Le reste, la mise en forme du mega menu notamment, n'est plus alors qu'une affaire de Magic CSS. Et ce n'est pas forcément le plus facile.

 

Ajouter un commentaire