6 page_example.module page_example_menu()
7 page_example.module page_example_menu()

Implementation of hook_menu().

hook_menu() must be implemented to emit items to place in the main menu. This is a required step for modules wishing to display their own pages, because the process of creating the links also tells Drupal what callback function to use for a given URL. The menu items returned here provide this information to the menu system.

With the below menu definitions, URLs will be interpreted as follows:

Note that the URLs below are written as though Clean URLs are not enabled on the site.

If the user accesses http://example.com/?q=examples/page_example, then the menu system will look for a menu item with that path. In this case it will find a match, and execute page_example_description().

If the user accesses http://example.com/?q=examples/page_example/simple but does not have the required 'access simple page' permission, access will be denied.

If http://example.com/?q=examples/page_example/arguments/1/2 is accessed, the menu system will first look for examples/page_example/arguments/1/2. Not finding a match, it will look for examples/page_example/arguments/1/%. Again not finding a match, it will look for examples/page_example/arguments/%/2. Yet again not finding a match, it will look for example/arguments/%/%. This time it finds a match, and so will execute page_example_arguments(1, 2). Note the parameters being passed; this is a very useful technique.

If http://example.com/?q=examples/page_example/arguments/1 is accessed, the menu system will match 'examples/page_example', and not 'examples/page_example/arguments/%/%'. The menu entries for the latter require 5 arguments. All the elements included in the menu entry definition should be present for the menu system to match the request.

If the user accesses http://example.com/?q=examples/page_example/different-permission but does not have the required 'access content' permission, access will be denied.

If the user accesses http://example.com/?q=examples/page_example/custom-access-callback but does not have the required 'access content' permission and/or is not signed in, access will be denied.

The Menu Example provides more extensive examples for hook_menu().

Related topics


page_example/page_example.module, line 108
This is an example outlining how a module can be used to display a custom page at a given URL.


function page_example_menu() {
  // This is the minimum information you can provide for a menu item. This menu
  // item will be created in the default menu (Navigation).
  // Specifying 'access callback' => TRUE causes this menu item to be
  // available for all roles.
  $items['examples/page_example'] = array(
    'title' => 'Page Example',
    'page callback' => 'page_example_description',
    'access callback' => TRUE,
    'expanded' => TRUE,

  // This example checks if the user has permission to access the page. Users
  // that do not have the 'access simple page' permission will be denied. An
  // array containing the required permissions is given in 'access arguments'
  // and here we use the default 'access callback', which is 'user_access'.
  $items['examples/page_example/simple'] = array(
    'title' => 'Simple - no arguments',
    'page callback' => 'page_example_simple',
    'access arguments' => array('access simple page'),

  // By using the MENU_CALLBACK type, we can register the callback for this
  // path but not have the item show up in the menu.
  // Notice that the 'page arguments' is an array of numbers. These will be
  // replaced with the corresponding parts of the menu path. In this case a 0
  // would be replaced by 'examples', a 1 by 'page_example', a 2 by 'arguments'
  // and likewise 3 and 4 will be replaced by whatever the user provides. We
  // will pass these last two as arguments to the page_example_arguments()
  // function.
  // Only users with the 'access arguments page' permission have access.
  $items['examples/page_example/arguments/%/%'] = array(
    'title' => 'Page example with arguments',
    'page callback' => 'page_example_arguments',
    'page arguments' => array(3, 4),
    'access arguments' => array('access arguments page'),
    'type' => MENU_CALLBACK,

  // You are not limited to checking for permissions defined by
  // this module. You can also check for permissions defined by
  // other modules. In this case, we will check for permissions
  // defined by node.module
  $items['examples/page_example/different-permission'] = array(
    'title' => 'Page example checking for other permissions',
    'page callback' => 'page_example_other_permissions',
    'access arguments' => array('access content'),

  // You can also define your own access callback function.
  $items['examples/page_example/custom-access-callback'] = array(
    'title' => 'Page example using a custom access callback',
    'page callback' => 'page_example_custom_access_page',
    'access callback' => 'page_example_custom_access_callback',
  return $items;