function menu_example_menu in Examples for Developers 6
Same name and namespace in other branches
- 7 menu_example/menu_example.module \menu_example_menu()
Implementatation of hook_menu().
Related topics
File
- menu_example/
menu_example.module, line 25 - Demonstrates uses of the Menu APIs in Drupal, including hook_menu(), hook_menu_alter(), and hook_menu_link_alter().
Code
function menu_example_menu() {
// The simplest kind of menu: A simple call to a function with a menu entry.
// The key of the menu item (menu_example/simplest) is the path that defines
// the menu router entry.
$items['menu_example'] = array(
// The menu type is not required, as we're using the default.
// 'type' => MENU_NORMAL_ITEM,
// The title - do NOT use t() as t() is called automatically.
'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('menu_example/path_only'),
)),
),
// This is to be accessible to all users, so 'access callback' can be set
// to TRUE, meaning that we should bypass all access checks.
'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['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' => 'primary-links',
'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['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">menu_example/permissioned/controlled</a>', array(
'!link' => url('menu_example/permissioned/controlled'),
)),
),
'access callback' => TRUE,
'expanded' => TRUE,
);
// Now provide the actual permissioned menu item.
$items['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 show 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,
);
// 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['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('menu_example/path_only/callback'),
)),
),
'access callback' => TRUE,
'weight' => 20,
);
$items['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 (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['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['menu_example/tabs/default'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => t('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["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['menu_example/tabs/default/first'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => t('Default secondary tab'),
);
foreach (array(
t('second'),
t('third'),
) as $tabname) {
$items["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['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('menu_example/use_url_arguments/one/two'),
'!link2' => url('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['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 '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['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">menu_example/placeholder_argument/3343/display</a>', array(
'!link' => url('menu_example/placeholder_argument/3343/display'),
)),
),
'access callback' => TRUE,
'weight' => 60,
);
// Now the actual entry.
$items['menu_example/placeholder_argument/%/display'] = array(
'title' => 'Placeholder Arguments',
'page callback' => '_menu_example_menu_page',
// Pass the value of '%', which is zero-based argument 2, to the
// 'page callback'. So if the URL is
// 'menu_example/placeholder_argument/333/display' then the value 333
// will be passed into the 'page callback'.
'page arguments' => array(
2,
),
'access callback' => TRUE,
);
// Drupal 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['menu_example/default_arg/%menu_example_arg_optional'] = array(
'title' => 'Processed Placeholder Arguments',
'page callback' => '_menu_example_menu_page',
'page arguments' => array(
2,
),
// arg 2 (3rd arg) is the one we want.
'access callback' => TRUE,
'weight' => 70,
);
$items['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 menu_example/menu_original_path. The hook_menu_alter() changes it to menu_example/menu_altered_path. You can try navigating to both paths and see what happens!'),
),
'access callback' => TRUE,
'weight' => 80,
);
return $items;
}