3

I have a module that I am working on that defines some local tasks and local actions for node pages, eg

$items['node/%node/foo'] = array(
  'title' => 'Foo',
  'page callback' => 'foo',
  'type' => MENU_LOCAL_TASK,
);

$items['node/%node/bar'] = array(
  'title' => 'Bar',
  'page callback' => 'bar',
  'type' => MENU_LOCAL_ACTION,
);

This works mostly great. 'Foo' appears as a new tab on node pages, and 'Bar' shows up as a local action on the 'node/%node' page.

I would like my 'node/%node/bar' local action to also show up on the 'node/%node/foo' page as a local action. Is this possible? I have tried playing with the 'tab_parent' and 'tab_root' parameters, but this only seems to work with local tasks and it also doesn't seem to allow multiple parents.

  • I am not sure about this but you may be able to do it by implementing hook_menu_local_tasks_alter and alter the $data['actions']['output'];. In any case, I feel like you are trying to convert a sibling relations ship between the menu items into a parent-child relationship. – awm Apr 20 '14 at 1:54
3
+250

I believe it's always Many (Local Actions) to one (Parent Item) relationship as hook_menu documentation says

MENU_LOCAL_ACTION: Local actions are menu items that describe actions on the parent item such as adding a new user or block, and are rendered in the action-links list in your theme.

If you want to change the parent of local action you can do it using tab_parent

  $items['node/%node/bar'] = array(
      'title' => 'Bar',
      'page callback' => 'bar',
      'access callback' => TRUE,
      'tab_parent' => 'node/%/foo',
      'type' => MENU_LOCAL_ACTION,
  );

Above displays action link in node/%/foo instead of node/% , tab_parent accepts single string argument... So we can rule out option of sending multiple parents using array.. For deeper analysis you can refer

function menu_local_tasks() in menu.inc which is responsible for action items and local tasks rendering..

If you would like to see it in action both places you can try below..

As @awm pointed out in comment we can add it to other pages using hook_menu_local_tasks_alter, Here is how node module does to include node/add menu item as local action to admin/content using hook_menu_local_tasks_alter

/**
 * Implements hook_menu_local_tasks_alter().
 */
function node_menu_local_tasks_alter(&$data, $router_item, $root_path) {
  // Add action link to 'node/add' on 'admin/content' page.
  if ($root_path == 'admin/content') {
    $item = menu_get_item('node/add');
    if ($item['access']) {
      $data['actions']['output'][] = array(
        '#theme' => 'menu_local_action',
        '#link' => $item,
      );
    }
  }
}

So you can do same for your own implementation using below code

/**
 * Implements hook_menu_local_tasks_alter().
 */
function YOURMODULENAME_menu_local_tasks_alter(&$data, $router_item, $root_path) {
  // Add action link to 'node/add' on 'admin/content' page.
  if ($root_path == 'node/%/foo') {
    $nid = arg(1);
    $item = menu_get_item('node/'. $nid . '/bar');
    if ($item['access']) {
      $data['actions']['output'][] = array(
          '#theme' => 'menu_local_action',
          '#link' => $item,
      );
    }
  }
}

Results in

enter image description here

  • 1
    Brilliant, thanks for the example. Didn't notice that when I was searching. – mpdonadio Apr 20 '14 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.