1 menu_example.module menu_example_menu()

Implements hook_menu().

A simple example which defines a page callback and a menu entry.

Related topics


modules/examples/menu_example/menu_example.module, line 29
Module file for menu_example.


function menu_example_menu() {
  // Menu items are defined by placing them in an $items array. The array key
  // (in this case 'menu_example') is the path that defines the menu router
  // entry, so the page will be accessible from the URL
  // example.com/examples/menu_example.
  $items['examples/menu_example'] = array(
    // We are using the default menu type, so this can be omitted.
    // 'type' => MENU_NORMAL_ITEM,
    // The menu title. Do NOT use t() which is called by default. You can
    // override the use of t() by defining a 'title callback'. This is explained
    // in the 'menu_example/title_callbacks' example below.
    'title' => 'Menu Example',

    // Description (hover flyover for menu link). Does NOT use t(), which is
    // called automatically.
    'description' => 'Simplest possible menu type, and the parent menu entry for others',

    // Function to be called when this path is accessed.
    'page callback' => '_menu_example_basic_instructions',

    // Arguments to the page callback. Here's we'll use them just to provide
    // content for our page.
    'page arguments' => array(t('This page is displayed by the simplest (and base) menu example. Note that the title of the page is the same as the link title. You can also <a href="!link">visit a similar page with no menu link</a>. Also, note that there is a hook_menu_alter() example that has changed the path of one of the menu items.', array('!link' => url('examples/menu_example/path_only')))),

    // If the page is meant to be accessible to all users, you can set 'access
    // callback' to TRUE. This bypasses all access checks. For an explanation on
    // how to use the permissions system to restrict access for certain users,
    // see the example 'examples/menu_example/permissioned/controlled' below.
    'access callback' => TRUE,

    // If the page callback is located in another file, specify it here and
    // that file will be automatically loaded when needed.
    // 'file' => 'menu_example.module',
    // We can choose which menu gets the link. The default is 'navigation'.
    // 'menu_name' => 'navigation',
    // Show the menu link as expanded.
    'expanded' => TRUE,

  // Show a menu link in a menu other than the default "Navigation" menu.
  // The menu must already exist.
  $items['examples/menu_example_alternate_menu'] = array(
    'title' => 'Menu Example: Menu in alternate menu',

    // Machine name of the menu in which the link should appear.
    'menu_name' => 'user-menu',

    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('This will be in the Primary Links menu instead of the default Navigation menu')),
    'access callback' => TRUE,

  // A menu entry with simple permissions using user_access().
  // First, provide a courtesy menu item that mentions the existence of the
  // permissioned item.
  $items['examples/menu_example/permissioned'] = array(
    'title' => 'Permissioned Example',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('A menu item that requires the "access protected menu example" permission is at <a href="!link">examples/menu_example/permissioned/controlled</a>', array('!link' => url('examples/menu_example/permissioned/controlled')))),
    'access callback' => TRUE,
    'expanded' => TRUE,

  // Now provide the actual permissioned menu item.
  $items['examples/menu_example/permissioned/controlled'] = array(

    // The title - do NOT use t() as t() is called automatically.
    'title' => 'Permissioned Menu Item',
    'description' => 'This menu entry will not appear and the page will not be accessible without the "access protected menu example" permission.',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('This menu entry will not show and the page will not be accessible without the "access protected menu example" permission.')),

    // For a permissioned menu entry, we provide an access callback which
    // determines whether the current user should have access. The default is
    // user_access(), which we'll use in this case. Since it's the default,
    // we don't even have to enter it.
    // 'access callback' => 'user_access',
    // The 'access arguments' are passed to the 'access callback' to help it
    // do its job. In the case of user_access(), we need to pass a permission
    // as the first argument.
    'access arguments' => array('access protected menu example'),

    // The optional weight element tells how to order the submenu items.
    // Higher weights are "heavier", dropping to the bottom of the menu.
    'weight' => 10,

   * We will define our own "access callback" function. We'll use
   * menu_example_custom_access() rather than the default user_access().
   * The function takes a "role" of the user as an argument.
  $items['examples/menu_example/custom_access'] = array(
    'title' => 'Custom Access Example',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('A menu item that requires the user to posess a role of "authenticated user" is at <a href="!link">examples/menu_example/custom_access/page</a>', array('!link' => url('examples/menu_example/custom_access/page')))),
    'access callback' => TRUE,
    'expanded' => TRUE,
    'weight' => -5,

  $items['examples/menu_example/custom_access/page'] = array(
    'title' => 'Custom Access Menu Item',
    'description' => 'This menu entry will not show and the page will not be accessible without the user being an "authenticated user".',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('This menu entry will not be visible and access will result in a 403 error unless the user has the "authenticated user" role. This is accomplished with a custom access callback.')),
    'access callback' => 'menu_example_custom_access',
    'access arguments' => array('authenticated'),

  // A menu router entry with no menu link. This could be used any time we
  // don't want the user to see a link in the menu. Otherwise, it's the same
  // as the "simplest" entry above. MENU_CALLBACK is used for all menu items
  // which don't need a visible menu link, including services and other pages
  // that may be linked to but are not intended to be accessed directly.
  // First, provide a courtesy link in the menu so people can find this.
  $items['examples/menu_example/path_only'] = array(
    'title' => 'MENU_CALLBACK example',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('A menu entry with no menu link (MENU_CALLBACK) is at <a href="!link">!link</a>', array('!link' => url('examples/menu_example/path_only/callback')))),
    'access callback' => TRUE,
    'weight' => 20,
  $items['examples/menu_example/path_only/callback'] = array(

    // A type of MENU_CALLBACK means leave the path completely out of the menu
    // links.
    'type' => MENU_CALLBACK,

    // The title is still used for the page title, even though it's not used
    // for the menu link text, since there's no menu link.
    'title' => 'Callback Only',

    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('The menu entry for this page is of type MENU_CALLBACK, so it provides only a path but not a link in the menu links, but it is the same in every other way to the simplest example.')),
    'access callback' => TRUE,

  // A menu entry with tabs.
  // For tabs we need at least 3 things:
  // 1) A parent MENU_NORMAL_ITEM menu item (examples/menu_example/tabs in this
  // example.)
  // 2) A primary tab (the one that is active when we land on the base menu).
  // This tab is of type MENU_DEFAULT_LOCAL_TASK.
  // 3) Some other menu entries for the other tabs, of type MENU_LOCAL_TASK.
  $items['examples/menu_example/tabs'] = array(
    // 'type' => MENU_NORMAL_ITEM,  // Not necessary since this is the default.
    'title' => 'Tabs',
    'description' => 'Shows how to create primary and secondary tabs',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('This is the "tabs" menu entry.')),
    'access callback' => TRUE,
    'weight' => 30,

  // For the default local task, we need very little configuration, as the
  // callback and other conditions are handled by the parent callback.
  $items['examples/menu_example/tabs/default'] = array(
    'title' => 'Default primary tab',
    'weight' => 1,
  // Now add the rest of the tab entries.
  foreach (array(t('second') => 2, t('third') => 3, t('fourth') => 4) as $tabname => $weight) {
    $items["examples/menu_example/tabs/$tabname"] = array(
      'type' => MENU_LOCAL_TASK,
      'title' => $tabname,
      'page callback' => '_menu_example_menu_page',
      'page arguments' => array(t('This is the tab "@tabname" in the "basic tabs" example', array('@tabname' => $tabname))),
      'access callback' => TRUE,

      // The weight property overrides the default alphabetic ordering of menu
      // entries, allowing us to get our tabs in the order we want.
      'weight' => $weight,

  // Finally, we'll add secondary tabs to the default tab of the tabs entry.
  // The default local task needs very little information.
  $items['examples/menu_example/tabs/default/first'] = array(
    'title' => 'Default secondary tab',
    // The additional page callback and related items are handled by the
// parent menu item.
  foreach (array(t('second'), t('third')) as $tabname) {
    $items["examples/menu_example/tabs/default/$tabname"] = array(
      'type' => MENU_LOCAL_TASK,
      'title' => $tabname,
      'page callback' => '_menu_example_menu_page',
      'page arguments' => array(t('This is the secondary tab "@tabname" in the "basic tabs" example "default" tab', array('@tabname' => $tabname))),
      'access callback' => TRUE,

  // All the portions of the URL after the base menu are passed to the page
  // callback as separate arguments, and can be captured by the page callback
  // in its argument list. Our _menu_example_menu_page() function captures
  // arguments in its function signature and can output them.
  $items['examples/menu_example/use_url_arguments'] = array(
    'title' => 'Extra Arguments',
    'description' => 'The page callback can use the arguments provided after the path used as key',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('This page demonstrates using arguments in the path (portions of the path after "menu_example/url_arguments". For example, access it with <a href="!link1">!link1</a> or <a href="!link2">!link2</a>).', array('!link1' => url('examples/menu_example/use_url_arguments/one/two'), '!link2' => url('examples/menu_example/use_url_arguments/firstarg/secondarg')))),
    'access callback' => TRUE,
    'weight' => 40,

  // The menu title can be dynamically created by using the 'title callback'
  // which by default is t(). Here we provide a title callback which adjusts
  // the menu title based on the current user's username.
  $items['examples/menu_example/title_callbacks'] = array(
    'title callback' => '_menu_example_simple_title_callback',
    'title arguments' => array(t('Dynamic title: username=')),
    'description' => 'The title of this menu item is dynamically generated',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('The menu title is dynamically changed by the title callback')),
    'access callback' => TRUE,
    'weight' => 50,

  // Sometimes we need to capture a specific argument within the menu path,
  // as with the menu entry
  // 'example/menu_example/placeholder_argument/3333/display', where we need to
  // capture the "3333". In that case, we use a placeholder in the path provided
  // in the menu entry. The (odd) way this is done is by using
  // array(numeric_position_value) as the value for 'page arguments'. The
  // numeric_position_value is the zero-based index of the portion of the URL
  // which should be passed to the 'page callback'.
  // First we provide a courtesy link with information on how to access
  // an item with a placeholder.
  $items['examples/menu_example/placeholder_argument'] = array(
    'title' => 'Placeholder Arguments',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('Demonstrate placeholders by visiting <a href="!link">examples/menu_example/placeholder_argument/3343/display</a>', array('!link' => url('examples/menu_example/placeholder_argument/3343/display')))),
    'access callback' => TRUE,
    'weight' => 60,

  // Now the actual entry.
  $items['examples/menu_example/placeholder_argument/%/display'] = array(
    'title' => 'Placeholder Arguments',
    'page callback' => '_menu_example_menu_page',

    // Pass the value of '%', which is zero-based argument 3, to the
    // 'page callback'. So if the URL is
    // 'examples/menu_example/placeholder_argument/333/display' then the value
    // 333 will be passed into the 'page callback'.
    'page arguments' => array(3),
    'access callback' => TRUE,

  // Backdrop provides magic placeholder processing as well, so if the placeholder
  // is '%menu_example_arg_optional', the function
  // menu_example_arg_optional_load($arg) will be called to translate the path
  // argument to a more substantial object. $arg will be the value of the
  // placeholder. Then the return value of menu_example_id_load($arg) will be
  // passed to the 'page callback'.
  // In addition, if (in this case) menu_example_arg_optional_to_arg() exists,
  // then a menu link can be created using the results of that function as a
  // default for %menu_example_arg_optional.
  $items['examples/menu_example/default_arg/%menu_example_arg_optional'] = array(
    'title' => 'Processed Placeholder Arguments',
    'page callback' => '_menu_example_menu_page',
    // Argument 3 (4rd arg) is the one we want.
    'page arguments' => array(3),
    'access callback' => TRUE,
    'weight' => 70,

  $items['examples/menu_example/menu_original_path'] = array(
    'title' => 'Menu path that will be altered by hook_menu_alter()',
    'page callback' => '_menu_example_menu_page',
    'page arguments' => array(t('This menu item was created strictly to allow the hook_menu_alter() function to have something to operate on. hook_menu defined the path as examples/menu_example/menu_original_path. The hook_menu_alter() changes it to examples/menu_example/menu_altered_path. You can try navigating to both paths and see what happens!')),
    'access callback' => TRUE,
    'weight' => 80,
  foreach ($items as $path => $item) {
    if (!isset($item['menu_name'])) {
      $items[$path]['menu_name'] = 'menu-example-menu';

  return $items;