Pre-requisites
Menus are differently structured lists of links to routes
In Drupal (not just 8) "menus" can mean several apparently different things:
- Hierarchical links, in several collections (each called a menu) that can be configured in both moduled and manually in the Drupal admin UI.
- Local tasks, which form a collection of tabs based around one core "default task".
- Local actions, which supplement the local tasks and provide "common other actions" that might be useful in particular context(s).
Ultimately, the word "menu" is applied to a curated (or curatable) list of links. In Drupal 8, a link means, as a minimum: some named route (discussed previously); plus the text that needs to go in the link tag.
From top to bottom, the diagram below shows these three different menu-ish areas of the page; in Drupal 8, these are called respectively menu links, local tasks and local actions:
These three menu-ish types of component are all configurable through YAML files, just like routing. In fact, they build on the work done by routing, turning named routes into menu links, as we'll see.
(Note that the official documentation on menus also talks about a fourth menu-ish thing: contextual links. We won't discuss these here, as implementing them is quite different from implementing the other three.)
Configuring menu links, local tasks and local tabs
As with routing YAML files, the three *.links.*.yml
files below consist of several bundles of configuration, each prefixed with an identifying "machine name" (again, see previous discussion of what this means.)
1. Menu links in .links.menu.yml
In the d8api
module we built previously, we can add a file in the top-level folder called d8api.links.menu.yml
containing the following:
d8api.index_link: route_name: d8api.index title: 'Menu link to tutorial index' menu_name: main
After the machine name identifying the top link, the three configuration lines specify: an existing route_name
from the d8api.routing.yml
we saved previously; the title
of the link, or rather the text that is shown on screen; and the menu_name
of the menu you want to add links to.
You can add as many chunks of configuration to this file as you want to, in the same pattern as the above. There are also other configuration keys you can add, including parent
to start to build a hierarchy of links, but we want to keep our example simple.
Also note that the machine name of your menu link can match the route name (and probably should, so you can keep track easier): but it needn't do so, especially if you need the same route to be present in more than one menu links hierarchy. We've made them different to show you can.
2. Local tasks in .links.task.yml
Let's define a couple of local task tabs in d8api.links.task.yml
, as we've got three of our own routes to choose from:
d8api.index_task: route_name: d8api.index title: 'Tutorial index' base_route: d8api.index d8api.sub_page_task: route_name: d8api.sub_page_for_druplicon title: 'Tutorial subpage' base_route: d8api.index
The only new configuration item here is base_route
. Every collection of tasks (tabs) is defined as a collection by a shared base route (default tab). And note again that you should try to make your local task's machine name (e.g. d8api.index_task
) match the route it references (e.g. d8api.index
): we only make them different here for clarity.
3. Local actions in .links.action.yml
Finally, we'll configure a local action. You probably won't use these very often, but when you do they can be very useful. Here's d8api.links.action.yml
:
d8api.index_action: route_name: d8api.index title: 'Skip to tutorial' appears_on: - d8api.index
Again, the machine name can and should match the route name; again, there's only one new configuration line in this example: appears_on
. An action is like a useful "you might also want to do this" link, that you can make appear on many other routes, if you think it will be useful there. For that reason, the value of this configuration is a YAML array: you can see the hyphen before - d8api.index
. You could add another line with e.g. - d8api.sub_page_with_parameter
on it, and the action would appear on both routes.
What you should see
With the files above in place, you should clear cache (see previously for how to do that.) In practice, you might need to clear caches a couple of times, for all the different YAML files to be able to cross-reference each other. [I found this to be the case when testing this tutorial, but like a lot of caching weirdnesses it was hard to repeat.]
If you then navigate to /tutorial
you should then see the following:
I haven't highlighted the relevant links on this image, as I found it hard to do so while not obscuring some of the test. But you should be able to see, from the top: a second menu link, alongside "Home"; two tabs for the local tasks, with "Tutorial index" highlighted (it corresponds to the current route); and then immediately underneath them, a local action.
If you see the same thing, then congratulations! you've configured the three main types of menu in Drupal.
Comments
kndr (not verified)
Wed, 11/01/2017 - 13:14
Permalink
Thank you very much for an
Thank you very much for an amazing tutorial. You are great! I've found a small typo in the following line:
base_route: d8apil.index
and it should be:
base_route: d8api.index
jp.stacey
Wed, 11/01/2017 - 14:45
Permalink
Thanks, kndr. You're quite
Thanks, kndr. You're quite right: the original namespace for the module in these tutorials was "tutorial", not "d8api": in the process of changing it, especially for the earlier tutorials, I occasionally introduced typos.
I'm always glad when people spot typos, though. It shows they're actually reading (and maybe even trying out) the code samples!
kndr (not verified)
Thu, 12/01/2017 - 09:53
Permalink
You can bet your bottom
You can bet your bottom dollar that I am trying out every piece of your excellent tutorial :) I'm really gratefull for your clear explanations without any unnecessary overhead. IMHO your tutorial is the best I've seen on the Internet. Keep going!