Aug 27, 2014

Defining a menu item in the system hierarchy

In D7 adding a normal menu item to the system hierarchy, for example, at the end of

  Home >> Administration >> Configuration >> System

involves defining the menu item in hook_menu() using something like this:

  $items['admin/config/system/optimizely'] = array(
    'title' => 'Optimizely',
    'description' => 'List of all ...',
    'type' => MENU_NORMAL_ITEM,

    // Other properties for  'page callback', 'file', etc.
  );

In Drupal 8 this is done quite differently. For the Optimizely module, there is a new file placed at the module root,

  optimizely.links.menu.yml

whose contents define menu items such as,

  optimizely.listing:
    title: Optimizely
    description: 'List of all ...'
    route_name: optimizely.listing
    parent: system.admin_config_system


route_name refers to a route that is defined in the optimizely.routing.yml file.

  optimizely.listing:
    path: /admin/config/system/optimizely
    defaults:
      _form: \Drupal\optimizely\ProjectListForm
      _title: Optimizely
    requirements:
      _permission: administer optimizely

To find the name of the menu item for the parent property, I did a string search of the path 'admin/config/system' across the core routing files. That turned up the route system.admin_config_system in the file system.routing.yml. Looking in system.links.menu.yml confirmed that system.admin_config_system is also the name of the corresponding menu item.

The name of the menu item, optimizely.listing, is by convention usually identical to its route_name. That's not a requirement, but it is a common convention that readily associates the menu item together with its route.

In D7 hook_menu() serves multiple purposes, whereas Drupal 8 distinguishes between routes and menu items and defines them in different files.

Sources:

Menu and routing system
https://api.drupal.org/api/drupal/core!includes!menu.inc/group/menu/8

2 comments:

  1. Yahoo for "routes and menu items being in different files". The combined functionality of hook_menu() of the past caused considerable confusion on my first encounter. Great see things getting restructured.

    ReplyDelete
    Replies
    1. I feel likewise. For example, in the D7 module's implementation of hook_help(), we have

      $items['ajax/optimizely'] = array(
         'title' => 'Optimizely Administer AJAX',
         'page callback' => 'optimizely_ajax_enable',
         'type' => MENU_CALLBACK,
         // Other properties, ...
      );

      This is the destination for an ajax call and has nothing to do with menus and menu items.

      As the documentation itself says, "Callbacks simply register a path so that the correct function is fired when the URL is accessed. They do not appear in menus or breadcrumbs."

      Delete