Hook_menu Drupal 7 creating pages via module
In the previous lesson, we looked at how to display information from the database using the Drupal API, specifically the hooks hook_block_info() and hook_block_view(). In this lesson, we will display pages using the hook_menu() hook to connect a page to other parts of Drupal such as menus, the translation module, templates, and more.
Let’s start with something simple: displaying the titles and descriptions of the latest 10 news articles. This will form a small news feed. We'll use the hook_menu() hook. Here's a description, followed by implementation.
hook_menu()
Defines menu items and returns pages.
This hook is invoked in a module to register paths that will be handled by Drupal. Paths may be for handling only, or they may appear in menus like the navigation menu. The paths and their associated metadata are known as "menu router items." This hook is invoked infrequently (e.g., when a module is enabled) and its results are cached in the database. Therefore, you must clear the cache when updating this hook.
hook_menu() returns an associative array whose keys are paths and whose values are associative arrays of properties for each path (described below).
The definition for each path includes a page callback, which returns content when the registered path is requested. For example, your module could register the path 'abc/def'.
'mymodule_abc_view', ); return $items; } function mymodule_abc_view($ghi = 0, $jkl = '') { // ... } ?>
When the path 'abc/def' is requested, and there are no additional segments in the URL, no extra arguments are passed. When 'abc/def/1/Omsk' is requested, the values "1" and "Omsk" will be passed to the callback. This is useful when creating page templates.
Additional arguments can be passed using an array. The array may include numeric indexes and literal values. When numbers are used, Drupal will pass the corresponding argument from the URL to the callback function. For example, the first segment can be retrieved using arg(0)
, the second with arg(1)
, and so on.
'mymodule_abc_view', 'page arguments' => array(1, 'foo'), ); return $items; } ?>
When the path 'abc/def' is called, the callback will receive 'def' as the first argument and always 'foo' as the second argument. Full documentation of the hook is available here: hook_menu API reference.
Let’s create a simple page:
function sitemade_menu(){ $items = array(); $items['page_example'] = array( 'title' => 'Page Example', 'description' => 'A simple page', 'page callback' => '_page_example', 'access callback' => TRUE, 'expanded' => TRUE, ); return $items; } function _page_example($content = NULL) { $content = ''; $query = db_select('node_revision', 'n'); $query->innerJoin('field_revision_body', 'b', 'b.revision_id = n.vid'); $query->innerJoin('node', 'd', 'n.nid = d.nid'); $query->fields('n', array('title'), array('nid'), array('vid')); $query->fields('b', array('body_value')); $query->condition('d.type', 'news'); $query->orderBy('n.timestamp', 'DESC'); $query->range(0, 10); $result = $query->execute(); while($nodes = $result->fetch()) { $content .= '' . $nodes->title . '
'; $content .= $nodes->body_value; } return $content; }
You can also use the type property to display the page in various menus, such as the admin or main menu.
Let’s do that:
function sitemade_menu(){ $items = array(); $items['page_example'] = array( 'title' => 'Page Example', 'description' => 'A simple page', 'page callback' => '_page_example', 'access callback' => TRUE, 'expanded' => TRUE, 'type' => MENU_NORMAL_ITEM, 'menu_name' => 'main-menu', ); return $items; }
Clear the cache and the menu link to this page will appear:
Besides standard menu items, we can display the page in the Drupal admin area:
function sitemade_menu(){ $items = array(); $items['admin/config/content/page_example'] = array( 'title' => 'Page Example', 'description' => 'A simple page', 'page callback' => '_page_example', 'access arguments' => array('administer site configuration'), ); return $items; }
Now the page will be visible only to admins and its link will appear in the admin interface:
The link appears in the admin interface because Drupal automatically places links under admin/config/content/*. If you change it to admin/config/people/*, the link will appear under the Users section (replace * with your path, such as page_example).
Now we know how to create blocks and pages. These are the essential hooks for displaying content and will frequently appear in your modules.
In the next lesson, we’ll explore hook_perm() for creating new user permissions.