Eve’s Drupal Tutorial Series, Episode #2
How do I add something to the menu?
Menus in drupal are really weird. Instead of hooking onto a function, they hook onto the path of a page. At least, that’s what I’ve gathered from looking at the code. I’m sure drupal experts don’t think about it and just visualize it in another way, but what you’re essentially doing is grabbing a series of ordered arguments and basing everything you write on that. So if your path is /node/add, arg(0) is “node” and arg(1) is “add”.
Actually, now that I’m typing it out, it makes sense. You grab a bunch of arguments from the path, then display based on those arguments. So by saying that a certain item has a certain path, you’re just saying that it’s associated with a certain sequence of arguments that the menu function can then use to build a menu. The way it’s done is crap, though; in order to display your function, you have to put it in a function called “menu.” This is really counter-intuitive, dontcha think?
(Upon later perusal I found this explanation as well. It’s all magically done by the menu_build() function. Turns out drupal has the documentation, but the API navigation is crap.)
Anyhoo, on to adding to a menu. To add a menu, you write a function that latches onto the menu hook. You do this by calling your function “module_menu.” Here’s part of the code for the translation module’s menu function:
function translation_menu($may_cache) {
$items = array(); // this just turns $items into an array
if ($may_cache) {
/* stuff that's been commented out */
} else {
}
return $items;
}
The $may_cache variable is part of drupal’s caching system. It’s explained well here. All youse gotta know is that items with dynamic paths (for example, those that depend on which node you’re looking at) go in the “else” part, and static paths (those that are always displayed the same way) go in the “may_cache” part. So let’s put some things in the “may_cache” part: an item that displays all the untranslated items in the database.
function translation_menu($may_cache) {
$items = array(); // this just turns $items into an array
if ($may_cache) {
$items[] = array('path' => 'node/add/untranslated',
'title' => t('translations'),
'callback' => 'find_untranslated_items',
'access' => user_access('translate nodes')
);
} else {
}
return $items;
}
In the above code, I’ve added a link to the menu that displays the function find_untranslated_items() when viewing the page at “node/add/untranslated”. “node/add” is listed as “create content” in the menu, so the “translations” title link will display under “create content” alongside “story” and “page”.
I’ve also indicated that people with permission to translate nodes have access to this item. There’s an additional option called “type” which I haven’t included, that allows you to define some of the properties of the item (like where it is displayed and how it’s used).
I’ll talk about the “else” part later, but here’s a full version of the code as a teaser:
function translation_menu($may_cache) {
$items = array(); // this just turns $items into an array
if ($may_cache) {
$items[] = array('path' => 'node/add/untranslated',
'title' => t('translations'),
'callback' => 'find_untranslated_items',
'access' => user_access('translate nodes')
);
} else {
if (arg(0) == 'node'
&& is_numeric(arg(1))
&& variable_get('i18n_node_'.translation_get_node_type(arg(1)),
0)) {
$access = user_access('translate nodes');
$type = MENU_LOCAL_TASK;
$items[] = array(
'path' => 'node/'. arg(1) .'/translation',
'title' => t('translation'),
'callback' => 'translation_node_page',
'access' => $access,
'type' => $type,
'weight' => 3);
}
if(arg(0) == 'admin'
&& arg(1) == 'taxonomy'
&& is_numeric(arg(2)) ) {
$items[] = array(
'path' => 'admin/taxonomy/'.arg(2).'/translation',
'title' => t('translation'),
'callback' => 'translation_taxonomy_admin',
'access' => user_access('administer taxonomy'),
'type' => MENU_LOCAL_TASK);
}
}
return $items;
}
WCG said,
July 25, 2006 at 10:40 pm
I heart Drupal, although the menuing system is extremely weak compare to, say, the Joomla Extended Menu component (which is, to be fair, an add-in and not even officially adopted by the latest Joomla distro). Also, the documentation is ass. If it was better documented and there were just a few more tutorials, Drupal would totally catch on in a mainstream way. Also if the ditch the frowny-plumber guy, and their catchphrase which is Community Plumbing which makes me think of ass cracks.
Eve said,
July 25, 2006 at 10:51 pm
I’ll community in their plumbing. Am I rite?