Adding Dynamic Values To The Menu Links In Drupal

December 8, 2020 | 3 Minute Read

Tags:Performance Optimization,Drupal

Understanding the Menu API in Drupal

In Drupal 8 the menu system, in comparison to Drupal 7 has become much more flexible, and the areas of functionality are now separated into different systems. 

The routing system now handles the following:

  • Association of path with the Controller
  • Combines access checking
  • Parameter up-casting
  • Serves as a basis for path access

The menu system is now a collection of: 

  • Different APIs for menu items
  • Local tasks
  • Contextual links defined by modules. 

While we were working on one of our client's projects, we came across a requirement where we had to have an admin for every country and allow them to add and edit the details. 

We decided to have the Country as a Vocabulary and the Countries as the terms in the vocabulary. The details of the Country are made available through fields in the vocabulary. Having done that, now we have every Country mapped to every Country admin. The term edit page should be made available to them as a menu link so that it’s easier to edit the details of the respective country, as shown in the screenshot below.

edit country details of backend

Defining Menu links

Menu links in Drupal 8 should be defined inside the module file following the convention module_name.links.menu.yml. Since menu-links are plugins themselves, they are discovered using the YAML discovery type.

Sample menu link definition: 

lines of code

Here the title key is required, and the route_name specifies the route the menu-link would point to.

By only specifying the parent link which is in a menu, we no longer need to mention the menu_name, as clearing the cache will get the menu link added to our menu.

Adding dynamic values to the menu link

With the use case that we discussed, we wanted to add a menu link to the edit page of a Country term that maps to the Country of the currently logged user.

The route to term edit page is entity.taxonomy_term.edit_form with the path /taxonomy/term/{taxonomy_term}/edit

Here the {taxonomy_term} is the route parameter that should be made available to the menu-link to switch paths dynamically.

lines of code

To make this route parameter available dynamically, we need to extend the MenuLinkDefault class, containing the required information for the default interaction.

Providing the route parameters using the Menu Link plugin class

lines of code

Using the getRouteParameters() function, we are passing the term id to the path - /taxonomy/term/{taxonomy_term}/edit

Now it’s available to the menu-link and changes dynamically when the user logs in.

Disabling menu-links dynamically

lines of code

In the above example, we wanted to enable the menu-link only if the country value is present. Here, passing the empty string could lead to a page with a broken link. 

So, we used the isEnabled() function to override the default functionality. Now, sending FALSE when the condition meets will disable the menu-link all together to the logged-in user.

This is one of the ways in which the menu-link could be altered dynamically. Other preferred methods could be to opt for hooks, commonly used  hook_menu_links_discovered_alter() for statically defined menu-links, hook_link_alter to alter the parameters for links. Here is the list of hooks the Menu API had to offer.