Thursday, September 13, 2012

Drupal menu system


The Drupal menu system was always much more than what the name suggests. It's not only used to display visible navigation menus but also to map Drupal paths to their callbacks with proper access checking. This second task is called dispatching. The likely rationale behind this; once you define a link to a page, you might want to define what happens when you click that link.
This eventually led to a very complex data structure which was stored as a serialized array in the database -- per user. Unserializing this on every non-cached page load uses tons of memory. Altering this either on build or run time needs dirty hacks.
Some misunderstandings about how access to an element applies to their children led to grave security holes with some contributed modules. This stresses the need for thought out, cleanly defined inheritance rules.
We have a new menu system in Drupal 6.x. The data is divided between two tables: {menu_router} and {menu_links}. The {menu_router} table is built based on the callbacks defined by implementations of hook_menu, and Drupal now looks in this table to determine access and the appropriate callback function when a site visitor tries to navigate to a particular path. Everything belonging to one path is one row in a database table, so the memory footprint is significantly smaller. The inheritance rules for access, etc. are cleanly laid out in the documentation. The {menu_links} table contains the links that are displayed in the Navigation and other menu blocks. Some of these items are derived automatically from {menu_router}, but others may be added by the site administrator using the menu module or other modules.
In hook_menu(), you define a menu array, which is an associative array. The keys are Drupal paths, the values are menu entries. One menu entry is again an associative array. A typical entry is:

<?php
  $items
['node/%node'] = array(
   
'title' => 'View',
   
'page callback' => 'node_page_view',
   
'page arguments' => array(1),
   
'access callback' => 'node_access',
   
'access arguments' => array('view', 1),
   
'type' => MENU_CALLBACK,
  );
?>
The menu builder collects these, applies inheritance rules and saves each entry in its row in the menu tables.
When you open a page, the system will generate the ancestors of the given path and ask the database for the menu entry of the ancestor that best fits this path. Then it calls the access callback to determine access. If it's given, it then hands over execution to the page callback.
The system determines that it has not found a path if no item can be retrieved from the database or if the node can not be loaded. Access denied is solely determined by the access callback/arguments.
The page callback function must return a non-NULL value, if any output is to be displayed in the browser for a given URL. If the function returns no value or a NULL value, Drupal will only render the content created by drupal_page_footer (which in turn is the content created by the hook_exit implementation of all the modules.)

Read More....

1 comment:

  1. Drupal technology provides a programming interface that has no programming skills required. Drupal is approved by GNU

    Drupal Development India

    ReplyDelete

only show translated menu items into current language (Drupal 8)

function MY_THEME_preprocess_menu(&$variables) {   if ($variables['menu_name'] == 'brancott-header-menu') {    $langu...