Overriding Menu Page Callbacks

10.11.2008

Sometimes you need to override more than a theme function: the entire page needs to be overridden. Drupal 6 makes it rather easy to do this.

In the example below, we call hook_menu_alter(&$callback) to override the display of every single node page view.

Instead of returning a node page, we return "[author's username] is great... for me to poop on.".

 

<?php
/**
* Implementation of hook_menu_alter().
* !!!!!!!!!!!!!must rebuild menus to take effect !!!!!!!!!!!!!
*/
function exampleModule_menu_alter(&$callbacks) {
 
$callbacks['node/%node']['page callback'] = 'fmtpo_page';
 
// it seems you have to override both when you're dealing with menu callback that is a default local task
 
$callbacks['node/%node/view']['page callback'] = 'fmtpo_page';
}

/**
*See "menu wildcards" if you are wondering how node made it into there.
*/
function fmtpo_page($node) {
 
// load the node's author's name -- this is personal...
 
$author = user_load(array( 'uid' => $node->uid));
  return
'<h3>'.$author->name.' is great...  for me to poop on</h3>';
}
?>

Discussion: Uses beyond telling authors they are great to poop on.

You can use this same technique to override anything defined in a menu array. The implication is that any page in drupal can be completely overridden -- whether its the menu callback, the access checking, or the page title.

The enterprising reader will no doubt think of applications of this technique that go far beyond this example.

Comments

I have always wondered

I have always wondered whether there is any other way to get past this problem without overriding but it seems to me that there is no other way left other than to override and that too greater than a theme function. The above examples shown clearly reveal how to do the above job but it seems to me that there is a slight error somewhere there. I say this because I seriously don't think that we can use this exact same technique to override everything which is defined in menu array. Thanks lil wayne

thanks for this stuff - a few

thanks for this stuff - a few lines of real code snippet sometimes saves hours and explains things better then documentation :)

insurance quotes

What if we want to alter menu

What if we want to alter menu by adding dynamic menu item.. is this possible in hook_menu_alter?

I want to add a dynamic menu item to my primary links..

lets say i have primary link as "link1" and "link2" and i want to add third link "link3" from hook_menu_alter()

Is this possible? if yes then any clue will be welcomed or is there any other way around.

Also it will be higly appriciated if some one let me know how to add a menu item in Primary links from Hook_menu()

Thanks
Qandeel

Hi Nick, thanks for this

Hi Nick,
thanks for this stuff - a few lines of real code snippet sometimes saves hours and explains things better then documentation :)

The function code is working

The function code is working great

function exampleModule_menu_alter(&$callbacks) {
$callbacks['node/%node']['page callback'] = 'fmtpo_page';
// it seems you have to override both when you're dealing with menu callback that is a default local task
$callbacks['node/%node/view']['page callback'] = 'fmtpo_page';
}

Regards
----------
Dizi izle

what if you only want to do

what if you only want to do this for an specific node typo and not for everynode?
I tried:

<?php
$node
= node_load(arg(3));
if(
$node->type == 'lyric'){
...
}
?>

but that's not working

Your way off -- almost always

Your way off -- almost always the $node->nid will be arg(1).

However, an even better way is to use the built in function menu_get_object():

<?php
$node
= menu_get_object();
if (
$node->type == 'lyric') {
// do a dance

}
?>

Right

Right