
Creating a responsive mega menu is often a regular prerequisite on any project, Drupal 8 or other. And if we can find some solutions offering to create mega menus easily, very often these solutions remain quite rigid and can hardly be adapted to the prerequisites of a project. But what is a mega menu? It is nothing more than a menu that contains a little more than a list of links (proposed by the menu system of Drupal 8), with specific links, text, images, call to actions, etc.
Rather than a rigid solution, which may be appropriate if we are willing to meet its requirements, we can also use a more flexible, open solution that also requires a little more work at the theming level. Let's find out how to build a mega menu with the Simple Mega Menu module.
General overview
The main idea of this module is based on two assumptions:
- A mega menu can be designed using all the power of the Field API of Drupal 8, in fact in the same way that we construct different content type by adding different field types to them.
- The final rendering is delegated to the Twig template engine, leaving a large margin of maneuver for positioning the different elements of a mega menu.
Simple mega menu is therefore not a solution out of the box that will provide you with a mega menu immediately usable (whatever it offers an example of mega menu pre-configured if one activates the example module). It simply allows to use a content entity as support for its mega menu, and thus to be able to use any type of field; Including links, references to content, images, videos, text, embedded widgets, views, and more. In short, everything you can do with the Drupal 8 content entity types.
For rendering the mega menu, the module provides two Twig functions:
- has_megamenu (item.url): lets you know if a menu link has a mega menu attached to it
- view_megamenu (item.url, view_mode): allows to display the mega menu in the specified display mode
With these two Twig functions, you can then display a mega menu in any ways, formatted from the twig template of the mega menu entity, to the exact place where you want to position your mega menu in relation to the menu link (and its possible children).
Let's find out more about how Simple Mega Menu works.
Creating a mega menu type
Once the module is installed, we need to create a mega menu type available in the Administration > Structure menu, at the URL /admin/structure/simple_mega_menu_type.
We create a mega menu entity type and we select for which menus the contents of this type of mega menu will be available.
Once the mega menu type saved we can then manage, like any content entity type, the different fields that will compose it, its view modes, form modes, etc.
Here we have added some fields
- Links: a multiple Link field
- Image: an image field
- Text: a long text field
- Bottom links: another link multiple field
We then configure the different view modes of our entity. By default, the module installs two view modes, Before and After. You can of course delete them, or add as many as you want.
Here we configure the Image and Text fields to be displayed in the Before view mode.
And the After view mode is configured to display only links from the Link field.
To add and configure other display modes, simply go to the configuration url (/admin/structure/display-modes/view) and add a new one.
To stay simple in this tutorial, we will not add the Bottom view mode, which we should configure to allow us to display only the Bottom Links field. But I think you have understood the principle.
After these few configuration operations, strictly similar to the management of content types, we have a mega menu type that will allow us to create our contents and associate these contents with elements of the targeted menu(s) selected previously.
You should also remember to set permissions to allow visitors or users of your site to view mega entities published or not.
Creating the mega menu contents
We can access from the menu Contents > Simple mega menu list to the list of mega menus entities created.
And of course we can create as many as necessary using the appropriate button.
And our first content of our mega menu is created.
Linking mega menu items to menu links
To display our first mega menu content, we must select it from the menu link for which we want to display this mega menu. To do this, a new field is available in the menu link form. Select (autocompletion field) the previously created mega menu from the Simple Mega menu field.
And here it is finished, or almost. You can repeat as many as necessary on the different links of your menu this operation. Also make sure that your menu block is configured correctly to display a sufficient menu depth.
By default, with the Twig template provided by the module, the mega menu attached to links will only be displayed if this link has child links. So make sure you have some child links on your main menu link.
If you do not have or do not want child links, just do it, just modify the default Twig template by copying it to your theme, and edit a few lines according to yours needs.
Customizing the mega menu with Twig
The Simple Mega Menu module provides a default template for menus, for menus that are targeted by a mega menu type. This template is just a simple override of the default Twig template included with Drupal 8, on which a few lines have been added. These few lines will allow you to inject each part of your mega menu to a very precise place of your menu HTML structure.
Let's discover this 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 %}
The most significant part of this template is of course where the mega menu is rendered.
<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>
Using the has_megamenu() function, we can test whether the link has a mega menu attached to it, using the view_mega_menu() function we can display our mega menu in any view mode. And we have complete freedom to position our mega menu according to our needs.
For example your main menu links do not have children links but just a mega menu. Modify this portion of code as well and the case is set.
<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>
You need a specific class for your main links containing a mega menu? Just add an extra class.
{% 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, ] %}
etc. etc.
Mega menus within range of Twig
This module does not offer a packaged solution within click range, just within range of Twig. But personally I think I have never been able to use such a solution, as the constraints are often multiple. And since the solution provided by this module is limited to just doing the necessary, namely to insert particular HTML markup within a list of classic menu links, this one remains compatible with any other module intervening on the menu system, modules that can offer you, for example, an amazing responsive menu such as those provided by the module Responsive and off-canvas menu.
This module allows us to offer a graphical interface to editors to update easily elements of a mega menu, relying mainly on the Drupal 8 core and its entities, while allowing a Drupal developer (or a developper front end knowing Twig) to precisely position these different elements, and to be able to get in a few hours a mega menu completely mastered. The rest, formatting of the mega menu in particular, is no longer a matter of Magic CSS. And it's not necessarily the easiest part.
Commentaires
elements, and to be able to get in a few hours a mega menu compl
l interface to editors to update easily elements of a mega menu, relying mainly on the Drupal 8 core and its entities, while allowing a Drupal developer (or a developper front end knowing Twig) to precisely position these different elements, and to be able to get in a few hours a mega menu completely mastered. The rest, formatting of the mega menu in particular, is no longer a matter of Magic CSS. And it's not necessarily the easiest part.
What about https://www…
What about https://www.drupal.org/project/menu_item_extras, it adds field to the core Menus?
Yes ? Seems this is a new…
Yes ? Seems this is a new alternative to build mega menu. You can give a try.
Great
Great job! Thank you so much. Finaly a usefull, maximum flexible megamenu solution in Drupal.
Thanks for your feedback.
Thanks for your feedback.
Library
Hi,
Thanks for the tutorial.
I just followed every steps but nothing happened at the end. No menu is displayed. Do I need to install a specific library? or to modify some twig template values according to the machine names I used?
only be displayed if this link has child links
Did you check this : "By default, with the Twig template provided by the module, the mega menu attached to links will only be displayed if this link has child links. So make sure you have some child links on your main menu link." ?
Sub menu dont appear.
Hi i have got the same behavior and solve it. We are used to set the main link targeting the megamenu to Show as expanded (disable). as the megamenu must be disable by default. It apear that with this module for the megamenu to popup you must set this parent link Show as expanded (enable) after that the mega menu will popup on link hovered.
(sorry for my bad english ) ;) good luck. And thanks to the author of this module, after testing other solution its seemed to be the cleener one ;)
Programmatically
Hi, how to alter a menu with D8, if an item of the menu is only visible for a certain role, how to unset this item if the current user have a different role ? Or another criteria....
I've been search for days, but I don't find anything.
Thanks
Ajouter un commentaire