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

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

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.