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,

whose contents define menu items such as,

    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.

    path: /admin/config/system/optimizely
      _form: \Drupal\optimizely\ProjectListForm
      _title: Optimizely
      _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 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.


Menu and routing system!includes!


  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.

    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."