Same name and namespace in other branches
  1. 4.6.x includes/menu.inc \menu
  2. 4.7.x includes/menu.inc \menu
  3. 5.x includes/menu.inc \menu
  4. 6.x includes/menu.inc \menu
  5. 7.x includes/menu.inc \menu
  6. 8.9.x core/lib/Drupal/Core/Menu/menu.api.php \menu
  7. 9 core/lib/Drupal/Core/Menu/menu.api.php \menu

Define the navigation menus, local actions and tasks, and contextual links.

Overview and terminology

The menu system uses routes; see the Routing API topic for more information. It is used for navigation menus, local tasks, local actions, and contextual links:

  • Navigation menus are hierarchies of menu links; links point to routes or URLs.
  • Menu links and their hierarchies can be defined by Drupal subsystems and modules, or created in the user interface using the Menu UI module.
  • Local tasks are groups of related routes. Local tasks are usually rendered as a group of tabs.
  • Local actions are used for operations such as adding a new item on a page that lists items of some type. Local actions are usually rendered as buttons.
  • Contextual links are actions that are related to sections of rendered output, and are usually rendered as a pop-up list of links. The Contextual Links module handles the gathering and rendering of contextual links.

The following sections of this topic provide an overview of the menu API. For more detailed information, see https://www.drupal.org/developing/api/8/menu

Routes for administrative tasks can be added to the main Drupal administrative menu hierarchy. To do this, add lines like the following to a module_name.links.menu.yml file (in the top-level directory for your module):


dblog.overview:
  title: 'Recent log messages'
  parent: system.admin_reports
  description: 'View events that have recently been logged.'
  route_name: dblog.overview
  options:
    query:
      uid: 1
  weight: -1

Some notes:

  • The first line is the machine name for your menu link, which usually matches the machine name of the route (given in the 'route_name' line).
  • parent: The machine name of the menu link that is the parent in the administrative hierarchy. See system.links.menu.yml to find the main skeleton of the hierarchy.
  • options: Define additional route options such as query parameters. See https://www.drupal.org/docs/8/api/menu-api/providing-module-defined-menu... for more information.
  • weight: Lower (negative) numbers come before higher (positive) numbers, for menu items with the same parent.

Discovered menu links from other modules can be altered using hook_menu_links_discovered_alter().

@todo Derivatives will probably be defined for these; when they are, add documentation here.

Defining groups of local tasks (tabs)

Local tasks appear as tabs on a page when there are at least two defined for a route, including the base route as the main tab, and additional routes as other tabs. Static local tasks can be defined by adding lines like the following to a module_name.links.task.yml file (in the top-level directory for your module):


my_module.admin:
  route_name: my_module.admin
  title: 'List'
  base_route: my_module.admin
my_module.settings:
  route_name: my_module.settings
  title: 'Settings'
  base_route: my_module.admin
  weight: 100

Some notes:

  • The first line is the machine name for your local task, which usually matches the machine name of the route (given in the 'route_name' line).
  • base_route: The machine name of the main task (tab) for the set of local tasks.
  • weight: Lower (negative) numbers come before higher (positive) numbers, for tasks on the same base route. If there is a tab whose route matches the base route, that will be the default/first tab shown.

Local tasks from other modules can be altered using hook_menu_local_tasks_alter().

@todo Derivatives are in flux for these; when they are more stable, add documentation here.

Defining local actions for routes

Local actions can be defined for operations related to a given route. For instance, adding content is a common operation for the content management page, so it should be a local action. Static local actions can be defined by adding lines like the following to a module_name.links.action.yml file (in the top-level directory for your module):


node.add_page:
  route_name: node.add_page
  title: 'Add content'
  appears_on:
    - system.admin_content

Some notes:

  • The first line is the machine name for your local action, which usually matches the machine name of the route (given in the 'route_name' line).
  • appears_on: Machine names of one or more routes that this local task should appear on.

Local actions from other modules can be altered using hook_menu_local_actions_alter().

@todo Derivatives are in flux for these; when they are more stable, add documentation here.

Defining contextual links

Contextual links are displayed by the Contextual Links module for user interface elements whose render arrays have a '#contextual_links' element defined. For example, a block render array might look like this, in part:


array(
  '#contextual_links' => array(
    'block' => array(
      'route_parameters' => array('block' => $entity->id()),
    ),
  ),

In this array, the outer key 'block' defines a "group" for contextual links, and the inner array provides values for the route's placeholder parameters (see @ref sec_placeholders above).

To declare that a defined route should be a contextual link for a contextual links group, put lines like the following in a module_name.links.contextual.yml file (in the top-level directory for your module):


block_configure:
  title: 'Configure block'
  route_name: 'entity.block.edit_form'
  group: 'block'

Some notes:

  • The first line is the machine name for your contextual link, which usually matches the machine name of the route (given in the 'route_name' line).
  • group: This needs to match the link group defined in the render array.

Contextual links from other modules can be altered using hook_contextual_links_alter().

@todo Derivatives are in flux for these; when they are more stable, add documentation here.

Rendering menus

Once you have created menus (that contain menu links), you want to render them. Drupal provides a block (Drupal\system\Plugin\Block\SystemMenuBlock) to do so.

However, perhaps you have more advanced needs and you're not satisfied with what the menu blocks offer you. If that's the case, you'll want to:

  • Instantiate \Drupal\Core\Menu\MenuTreeParameters, and set its values to match your needs. Alternatively, you can use MenuLinkTree::getCurrentRouteMenuTreeParameters() to get a typical default set of parameters, and then customize them to suit your needs.
  • Call \Drupal\Core\MenuLinkTree::load() with your menu link tree parameters, this will return a menu link tree.
  • Pass the menu tree to \Drupal\Core\Menu\MenuLinkTree::transform() to apply menu link tree manipulators that transform the tree. You will almost always want to apply access checking. The manipulators that you will typically need can be found in \Drupal\Core\Menu\DefaultMenuLinkTreeManipulators.
  • Potentially write a custom menu tree manipulator, see \Drupal\Core\Menu\DefaultMenuLinkTreeManipulators for examples. This is only necessary if you want to do things like adding extra metadata to rendered links to display icons next to them.
  • Pass the menu tree to \Drupal\Core\Menu\MenuLinkTree::build(), this will build a renderable array.

Combined, that would look like this:

$menu_tree = \Drupal::menuTree();
$menu_name = 'my_menu';

// Build the typical default set of menu tree parameters.
$parameters = $menu_tree
  ->getCurrentRouteMenuTreeParameters($menu_name);

// Load the tree based on this set of parameters.
$tree = $menu_tree
  ->load($menu_name, $parameters);

// Transform the tree using the manipulators you want.
$manipulators = array(
  // Only show links that are accessible for the current user.
  array(
    'callable' => 'menu.default_tree_manipulators:checkAccess',
  ),
  // Use the default sorting of menu links.
  array(
    'callable' => 'menu.default_tree_manipulators:generateIndexAndSort',
  ),
);
$tree = $menu_tree
  ->transform($tree, $manipulators);

// Finally, build a renderable array from the transformed tree.
$menu = $menu_tree
  ->build($tree);
$menu_html = \Drupal::service('renderer')
  ->render($menu);

File

core/lib/Drupal/Core/Menu/menu.api.php, line 8
Hooks and documentation related to the menu system and links.

Functions

Namesort ascending Location Description
hook_system_breadcrumb_alter core/lib/Drupal/Core/Menu/menu.api.php Perform alterations to the breadcrumb built by the BreadcrumbManager.
hook_menu_local_tasks_alter core/lib/Drupal/Core/Menu/menu.api.php Alter local tasks displayed on the page before they are rendered.
hook_menu_local_actions_alter core/lib/Drupal/Core/Menu/menu.api.php Alter local actions plugins.
hook_menu_links_discovered_alter core/lib/Drupal/Core/Menu/menu.api.php Alters all the menu links discovered by the menu link plugin manager.
hook_local_tasks_alter core/lib/Drupal/Core/Menu/menu.api.php Alter local tasks plugins.
hook_contextual_links_plugins_alter core/lib/Drupal/Core/Menu/menu.api.php Alter the plugin definition of contextual links.
hook_contextual_links_alter core/lib/Drupal/Core/Menu/menu.api.php Alter contextual links before they are rendered.

Interfaces

Namesort ascending Location Description
ContextualLinkInterface core/lib/Drupal/Core/Menu/ContextualLinkInterface.php Defines a contextual link plugin.