28
Drupal Menu System By: Anirudha Prabhune Mail:[email protected]

DRUPAL Menu System

Embed Size (px)

DESCRIPTION

How to make Drupal behavior flexible according to requirements using Access Control, Menu Customization & Callback Mapping.

Citation preview

Page 1: DRUPAL Menu System

Drupal Menu System

By: Anirudha Prabhune

Mail:[email protected]

Page 2: DRUPAL Menu System

Menu System

The Menu System has three primary responsibilities:

callback mapping access control menu customization

Page 3: DRUPAL Menu System

Callback Mapping

• When a request is made to Drupal by a browser, a URL is given to Drupal.

• From this information, Drupal must figure out what code to run and how to handle the request. This is commonly known as dispatching.

Page 4: DRUPAL Menu System

Mapping URLs to Functions• The general approach taken is as follows:

Drupal asks all its modules to provide an array of menu items—that is, a path and some information about that path. One of the pieces of information a module must provide is a callback.

• A callback in this context is simply the name of a PHP function that will be run when the browser requests a certain path.

Page 5: DRUPAL Menu System

Mapping URLs to Functions

Drupal goes through the following steps when a request comes in:

1. If the path is an alias to a real path, Drupal finds the real path and uses it instead.

2. Executes hook_menu() so that all modules can provide their callbacks.

3. Creates a map from paths (such as node/add) to callbacks (PHP functions such as node_page()).

Cont..

Page 6: DRUPAL Menu System

Mapping URLs to Functions

4. If menu.module is enabled, applies any changes or additions the site administrator has made to the map (such as overriding a menu item’s title).

5. Uses the map to look up the callback function for the requested URL, and calls it. If any callback arguments were specified, Drupal sends those along.

6. Returns the function’s result or an “Access denied” message if the user may not access the URL, or a 404 response if the path did not map to any function.

Page 7: DRUPAL Menu System

Process Representation

Menu Array

Page 8: DRUPAL Menu System

A Sample Module

• A module named new_menu.module that places a menu item in Drupal’s navigation menu is coded here.

• The Drupal path new_menu is mapped to the PHP function new_menu_hello().

Page 9: DRUPAL Menu System

A Demo Menufunction new_menu_menu($may_cache)

{

$items = array();

if ($may_cache)

{

$items[] = array(

'title' => t('My Menu'),

'path' => 'admin/settings/new_menu',

'callback' => 'new_menu_hello',

'callback arguments' => array(t('Menu!'), t('Nested Menu!')),

'access' => TRUE

);

Page 10: DRUPAL Menu System

A Demo Menu$items[] = array(

'title' => t('Done'),

'path' => 'admin/settings/new_menu/MyMenu',

'callback' => 'new_menu_hello',

'callback arguments' => array(t('Menu!'), t('Nested Menu!')),

'access' => TRUE

);

}

return $items;

}

Page 11: DRUPAL Menu System

A Demo Menufunction new_menu_hello($first,$second,$name = NULL)

{

drupal_set_message(t('First comes %first', array('%first' => $first)));

drupal_set_message(t('Second comes %second', array('%second' => $second)));

if (!isset($name))

{

$name = t('good looking!');

}

return t('Hello @name!', array('@name' => $name));

}

Page 12: DRUPAL Menu System

Visual Demo

Nested Menu

Page 13: DRUPAL Menu System

Access ControlPreviously we’ve simply set the access key of the

menu item to TRUE, meaning that anyone can access our menu. Usually menu access is controlled by defining permissions inside the module using hook_perm() and testing those permissions using user_access().

Let’s define a permission called Door Opened!!; if a user does not have a role that has been granted this permission, the user will receive an “Access denied” message if he or she tries to access that particular menu.

Page 14: DRUPAL Menu System

Access Controlfunction new_menu_perm()

{

return array('Door Opened!!');

}

Replace

‘access’ => TRUE WITH

‘access’ => user_access(‘Door Opened!!’)

In this way, the menu system serves as a gatekeeper determining which paths may be accessed and which will be denied based on the user’s role.

Note: Do not forget to apply the Access Control from Administer Panel Manually.

Page 15: DRUPAL Menu System

Access ControlWhen determining access to a menu item, Drupal will look at the access key of the menu item’s full path and use that. If the access key is TRUE, access will be granted even if the parent’s access key is FALSE. If there is no access key assigned to a menu item, its parent’s access key will be used. If the parent does not have an access key, Drupal will recurse all the way up the tree until it finds an access key (the access key for the root of the tree is TRUE). Local tasks are common nested menu items.

Page 16: DRUPAL Menu System

Access ControlAccess Settings and Resulting User Access Table

Parent Child User Access

FALSE FALSE Denied

TRUE FALSE Denied

FALSE TRUE Allowed

TRUE TRUE Allowed

FALSE Undefined Denied

TRUE Undefined Allowed

Page 17: DRUPAL Menu System

Kinds of MenuWhen you are adding a menu item in the menu

hook, one of the possible keys you can use is the type. If you do not define a type, the default type MENU_NORMAL_ITEM will be used. Drupal will treat your menu item differently according to the type you assign. Each menu item type is composed of a series of flags, or attributes.

The Following Table lists the menu item type FLAGS:

Page 18: DRUPAL Menu System

Kinds of Menu

Binary Hexadecimal Decimal Constant

000000000001 0x0001 1 MENU_IS_ROOT

000000000010 0x0002 2 MENU_VISIBLE_IN_TREE

000000000100 0x0004 4 MENU_VISIBLE_IN_BREADCRUMB

000000001000 0x0008 8 MENU_VISIBLE_IF_HAS_CHILDREN

000000010000 0x0010 16 MENU_MODIFIABLE_BY_ADMIN

000000100000 0x0020 32 MENU_MODIFIED_BY_ADMIN

000001000000 0x0040 64 MENU_CREATED_BY_ADMIN

000010000000 0x0080 128 MENU_IS_LOCAL_TASK

000100000000 0x0100 256 MENU_EXPANDED

001000000000 0x0200 512 MENU_LINKS_TO_PARENT

Page 19: DRUPAL Menu System

Kinds of MenuFor example, the constant MENU_NORMAL_ITEM has the

flags MENU_VISIBLE_IN_TREE, MENU_VISIBLE_IN_BREADCRUMB, and MENU_MODIFIABLE_BY_ADMIN, as shown in Table . See how the separate flags can be expressed in a single constant?

Binary Constant

000000000010 MENU_VISIBLE_IN_TREE

000000000100 MENU_VISIBLE_IN_BREADCRUMB

000000010000 MENU_MODIFIABLE_BY_ADMIN

000000010110 MENU_NORMAL_ITEM

Page 20: DRUPAL Menu System

Common TasksAssigning Callbacks Without Adding a Link to the MenuOften we want to map a URL to a function without creating a visible menu item. We can do this

by assigning the MENU_CALLBACK type to your menu item, as in this example from node.module:

$items[] = array(

‘path' => 'rss.xml',

'title' => t('RSS feed'),

'callback' => 'node_feed',

'access' => user_access('access content'),

'type' => MENU_CALLBACK

);

Page 21: DRUPAL Menu System

Common Tasks

Programmatically Modifying Existing Menus:

When we implement the menu hook in our module, there’s nothing to prevent us from adding entries to other modules’ paths, or even from overriding them. Typically this is done using the handy web interface provided by menu.module, which ships as part of Drupal, but we have reasons to do this programmatically.

Page 22: DRUPAL Menu System

Common TasksWrapping Calls to Menu Items:

For example, devel.module has a menu item that clears Drupal’s cache tables. Let’s wrap that function so our function gets called first. First, we override devel.module’s menu item by specifying one of our own with the same path inside our menu hook

Page 23: DRUPAL Menu System

Common Tasksfunction mymodule_menu($may_cache) {

$items = array();

if (!$may_cache && module_exist('devel')) { // Make sure devel.module is enabled.

$items[] = array(

'path' => 'devel/cache/clear', // Same path that devel.module uses.

'title' => t('Wrap cache clear'),

'callback' => 'mymodule_clear_cache',

'type' => MENU_CALLBACK,

'access' => user_access('access devel information') // Same as devel.module.

);

}

}

function mymodule_clear_cache() {

drupal_set_message('We got called first!');

// Wrap the devel function normally called.

devel_cache_clear();

}

Page 24: DRUPAL Menu System

Common Tasks• Now when we go to the menu ../?q=devel/cache/clear,

our module will be called first, and it will call the function that would have originally been called. Here’s the result:

We got called first!

Cache cleared.

Note : This is a useful technique for when you want to modify Drupal’s default behavior without modifying any underlying code.

Page 25: DRUPAL Menu System

Common TasksDeleting Existing Menus:Using the same approach presented in the section “Wrapping Calls to

Menu Items,” we can delete existing menu items by overriding their paths. Suppose you want to remove the “create content” menu item and the ability to add content, for some reason:

$items[] = array(

'path' => 'node/add',

'title' => t('This should not show up'),

'callback' => 'drupal_not_found',

‘type' => MENU_CALLBACK

);

Page 26: DRUPAL Menu System

Common TasksAdding to Existing Menus:

We can add to existing menus by inserting our menu item with a clever path. For example, suppose we want to add a tab to the user administration interface to delete all users. By examining the menu hook in user.module, we determine that admin/user is the path we want to use as our base path. Here’s the menu item we return from eradicateusers.module:

Page 27: DRUPAL Menu System

Common Tasks$items[] = array(

'path' => 'admin/user/eradicate',

'title' => t('Eradicate all users'),

'callback' => 'mymodule_eradicate_users',

'type' => MENU_LOCAL_TASK,

'access' => user_access('eradicate users')

);

This adds the menu item as a local task. If we want the menu item to show up in the administrative menu block, we have to make the type a MENU_NORMAL_ITEM instead of a MENU_LOCAL_TASK. And if we want it to show up in both places, use the following:

'type' => MENU_NORMAL_ITEM | MENU_LOCAL_TASK

and the menu item will have the attributes of both menu item types.

Page 28: DRUPAL Menu System

THANK YOU