Can't add MENU_LOCAL_TASK to specific node-types

ryan_courtnage - September 12, 2008 - 14:31
Project:Drupal
Version:6.8
Component:menu system
Category:support request
Priority:minor
Assigned:Unassigned
Status:closed
Description

This issue was previously discussed in the forums. With Drupal 6's new menu system, there appears to be no way for a module to define a MENU_LOCAL_TASK (a tab) that only applies to certain node types.

For example, to add a new tab for ALL node types, do:

<?php
$items
['node/%node/new_tab'] = array(
   
'title' => 'New Tab',
   
'page callback' => 'mycallback',
   
'page arguments' => array(1),
   
'access callback'   => TRUE,
   
'type' => MENU_LOCAL_TASK
)
?>

In D5, we could use hook_menu !$may_cache to conditionally create the tab based on the node type. This is not available in D6.

One possible workaround is to use the 'access callback' key to check for the node type and return false when needed:

<?php
$items
['node/%node/new_tab'] = array(
   
'title' => 'New Tab',
   
'page callback' => 'mycallback',
   
'page arguments' => array(1),
   
'access callback'   => check_type(arg(1)),
   
'type' => MENU_LOCAL_TASK
)

function
check_type($node)
{
  if(
$node->type == 'story')
    return
TRUE;
  }
  return
FALSE;
}
?>

This will work for non-admin users. However when you are admin (user 1), the 'access callback' check is skipped. This results in node pages with irrelevant tabs on them.

#1

ryan_courtnage - September 12, 2008 - 20:01
Status:active» closed

Turns out the workaround using 'access callback' does work, even for user 1.

#2

Damien Tournoud - September 12, 2008 - 20:28

The best way remains to define your own loader. Using access callback for this is simply ugly.

#3

ryan_courtnage - September 12, 2008 - 20:35

Can you please elaborate? Do you mean do something like:

<?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;
}
?>

?

Dang, i never considered that before. I'll have to try!

#4

Damien Tournoud - September 12, 2008 - 20:43

I meant exactly that.

#5

axelc - December 23, 2008 - 22:38

If you have 5 tabs definied, does that mean that the node gets loaded 5 times ? Or is there a workaound ?

$items['node/%my_node_type/new_tab']= array(...
$items['node/%my_node_type/new_tab1']= array(...
$items['node/%my_node_type/new_tab2']= array(...
$items['node/%my_node_type/new_tab3']= array(...
$items['node/%my_node_type/new_tab4']= array(...
...

function my_node_type_load($arg) {
$node = node_load($arg);
if($node->type == 'my_type')
return $node;
return FALSE;
}

#6

Apfel007 - January 12, 2009 - 12:47

Hi, did you solve this problem?

Can you give me the whole code to implement a tab? I can't figure it out.

Cheers

#7

webcurl - January 16, 2009 - 01:39
Version:6.4» 6.8

I am having real problems just getting the tabs to appear on all nodes. Does the code above need to be placed in a hook_menu or just as php inside my module? can someone post the full code for a module including a sample page callback as this is possible where my error lies. I am just returning a string from my callback for testing purposes.

Thanks.

#8

hamaldus - January 27, 2009 - 10:54
Category:bug report» support request
Priority:normal» minor
Status:closed» active

As Apfel007 mentioned, could someone post a complete working code for us noobs to learn from? :)

#9

radman16 - February 28, 2009 - 06:41

It goes into hook_menu in a custom module named my_module (or whatever you want to call it). Here is some working code:

/**
* Implementation of hook_menu().
*/
function my_module_menu() {
$items['node/%/new_tab'] = array(
'title' => 'Pay Here',
'page callback' => 'mycallback',
'page arguments' => array(1),
'access callback' => 'custom_loader',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
);
return $items;
}

function custom_loader($param) {
$node = node_load($param , $revision = NULL, $reset = NULL);
if($node->type == 'my_node_type')
return TRUE;
return FALSE;
}
/**
* Menu callback; do whatever you want the tab to do here.
*/
function mycallback($param) {
$node = node_load($param , $revision = NULL, $reset = NULL);
// Do cool stuff here
return ;
}

#10

hamaldus - February 28, 2009 - 10:50
Status:active» fixed

Beautiful! Thank you!

#11

System Message - March 14, 2009 - 11:00
Status:fixed» closed

Automatically closed -- issue fixed for 2 weeks with no activity.

#12

ncameron - June 3, 2009 - 19:36

Don't forget to clear your menu caches when testing!

 
 

Drupal is a registered trademark of Dries Buytaert.