Last updated August 7, 2008. Created by clemens.tolboom on December 13, 2006.
Edited by beginner, sdboyer, webchick, Robert Castelo. Log in to edit this page.
Cached part
This is very simple, a search-and-replace operation. Here is a list of changes:
- hook_menu() no longer takes any parameters (remove
$may_cache). - The value of
pathis the new index for$items. callbackbecomespage callbackcallback argumentsbecomespage argumentsaccessbecomesaccess callbackandaccess arguments.For example,
access => user_access('administer nodes')becomes'access callback' => 'user_access', 'access arguments' => array('administer nodes').However, the default for
'access callback'is'user_access'so you can leave that out.Complex access things must be moved to a function which can be called on runtime,
user_is_anonymousanduser_is_logged_inare useful helpers. See Access control for more.- The title and description arguments should not have strings wrapped in t(), because translation of these happen in a later stage in the menu system. This allows translation of menu items to any language required on a site, adapting to the language used on the page.
Non-cached part
Let's suppose you had
<?php
/**
* Implementation of hook_menu().
*/
function aggregator_menu($may_cache) {
if (!$may_cache) {
if (arg(0) == 'aggregator' && is_numeric(arg(2))) {
if (arg(1) == 'sources') {
$feed = aggregator_get_feed(arg(2));
if ($feed) {
$items[] = array('path' => 'aggregator/sources/'. $feed['fid'] .'/configure',
'title' => t('Configure'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_form_feed', $feed),
'access' => user_access('administer news feeds'),
'type' => MENU_LOCAL_TASK,
'weight' => 1);
}
}
}
}
return $items;
}
?>this becomes
<?php
/**
* Implementation of hook_menu().
*/
function aggregator_menu() {
$items['aggregator/sources/%aggregator_feed/configure'] = array(
'title' => 'Configure',
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_feed', 2),
// NOTE: as of Drupal 6.2, all menu items are *required* to have
// access control.
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
return $items;
}
?>If we would use just a percent sign aggregator/sources/%/configure it'd match everything, including non-numeric values as well, like aggregator/sources/foo/configure. However, with %aggregator_feed we ask for a feed to be loaded based on the third argument and anything that's not a valid feed will lead to a 404.
About the use of wildcards, foreach() loops and MENU_ITEMs
In Drupal 5, we used to use foreach() loops to recursively declare several MENU_ITEMs or MENU_SUGGESTED_ITEMs.
In Drupal 6, we only need one entry in hook_menu() with the use of a proper wildcard. Additionally, you can create as many menu items (enabled or not) as you see fit with menu_link_save().
For a detailed discussion on this topic, see this issue.
Additional Run Once Code
Non menu code that was placed in hook_menu !$may_cache so that it could be run during initialisation, should now be moved to hook_init. Previously we called hook_init twice, once early in the bootstrap process, second just after the bootstrap has finished. The first instance is now called boot instead of init.
If you were using a loop in your menu code then you likely need menu_link_save.
A horribly complex example can be found in the menu of http://drupal.org/files/issues/akismet.d6-port.patch. It involves just about every possible path manipulation trick one could ever need for the path akismet/%akismet/%/'. $op, and then some. It passes the real page callback in $map[0] which is a bit of a hack, but is also quite useful.
Comments
Upgrading to version 6 menu system
Thanks,
To make the code comparable shouldn't the version 6 be:
$items['aggregator/sources/%aggregator_get_feed/configure'] = array(It blows my mind a bit that the 2 in:
'page arguments' => array('aggregator_form_feed', 2),
is the result of calling a function on the second argument, and so could be a different type (a whole feed) than was in the original URL.
Good on ya!!
PS you might want to put Drupal 6 somewhere in the title
Actually, they are assuming
Actually, they are assuming you would rename the function to 'aggregator_feed_load', as the '_load' part is automatically added to the loader function's name before calling. That should probably be noted as part of the process as it's a little bit misleading as to how the wildcarding works.
aggregator_feed_load is an existing wildcard loader
aggregator_feed_load is an existing wildcard loader!
See http://api.drupal.org/api/function/aggregator_feed_load/6 for definition.
For more information on existing wildcard loaders - http://drupal.org/node/209056.
hope that helps..
Adding MENU_LOCAL_TASK items for your node-type
If you need to add a MENU_LOCAL_TASK for a specific node-type, use a loader:
<?php
$items['node/%my_node_type/new_tab'] = array(
'title' => 'New Tab',
'page callback' => 'mycallback',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_LOCAL_TASK
)
...
function my_node_type_load($arg) {
$node = node_load($arg);
if($node->type == 'my_type')
return $node;
return FALSE;
}
?>
how to deal with if...else statements in menu_hook
IN one of the module i am trying to port from 5x to 6x. the menu_hook has the following colde
if ($may_cache)
{
code goes here
}
else
{
different code goes here
}
My question is since Drupal6 menu_hook doesnot take $may_cache parameters how can i write a if..else statement if i remove $may_cache from above? any suggestions would be greatly appreciated.
Regards,
judef
judef
Did you see this portion of
Did you see this portion of the above text?
-Blake
www.BlakeSenftner.com www.MissingUbercartManual.com www.cg-general-store.com www.droplabs.net