0

I've successfully managed to hide "View" tab on node page with this code:

/*
 * Implements hook_menu_local_tasks_alter().
 */
function mymodule_menu_local_tasks_alter(&$data){


    foreach ($data['tabs'][0]['output'] as $key => $value) {
        if ($value['#link']['path'] == "node/%/view"){
            unset($data['tabs'][0]['output'][$key]);
        }
    }
}

but when I enter the frontpage this error is displayed:

Notice: Undefined offset: 0 in custom_alter_menu_local_tasks_alter()... Warning: Invalid argument supplied for foreach() in custom_alter_menu_local_tasks_alter()...

This line that causes the error is the following.

foreach ($data['tabs'][0]['output'] as $key => $value) {

I don't know what is wrong with the code. On frontpage there are no tabs and I don't have custom coding there.

I'm using Drupal 7.

1

I dont know what is your purpose but to pass this error you just do that

/*
 * Implements hook_menu_local_tasks_alter().
 */
function mymodule_menu_local_tasks_alter(&$data){
  if(isset($data['tabs'][0]) && is_array($data['tabs'][0])){
    foreach ($data['tabs'][0]['output'] as $key => $value) {
      if ($value['#link']['path'] == "node/%/view"){
        unset($data['tabs'][0]['output'][$key]);
      }
    }
  }
}
  • Yes, this code is OK. Now I don't have the error. I can see the correction. If statement with this line: if(isset($data['tabs'][0]) && is_array($data['tabs'][0])){ Thanks! – user2519032 Oct 1 '13 at 8:59
  • Actually, this is not the correct hook to implement. The hook that should be used to alter menu items defined from another module is hook_menu_alter(). – kiamlaluno Oct 1 '13 at 9:21
  • That's right. With hook_menu_alter() it will be simple. Reference : drupal.org/node/483324 – Stone Vo Oct 1 '13 at 9:24
2

The way to hide the node/%/view tab is to implement hook_menu_alter(), and change the menu defined from the Node module, which uses the following definitions.

  $items['node/%node'] = array(
    'title callback' => 'node_page_title',
    'title arguments' => array(1),

    // The page callback also invokes drupal_set_title() in case
    // the menu router's title is overridden by a menu link.
    'page callback' => 'node_page_view',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('view', 1),
  );
  $items['node/%node/view'] = array(
    'title' => 'View',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['node/%node/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'node_page_edit',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('update', 1),
    'weight' => 0,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
    'file' => 'node.pages.inc',
  );

In particular, you need to change the menu type for node/%node/view from MENU_DEFAULT_LOCAL_TASK to MENU_CALLBACK, and change the type for node/%node/edit from MENU_LOCAL_TASK to MENU_DEFAULT_LOCAL_TASK.

MENU_CALLBACK keeps the menu item still accessible for those users who have the permission to see it, but the menu item would not be visible as tab or link.

As for using hook_local_task_alter(), I don't see Drupal core modules that alter the tabs added from other modules, but looking at blog_local_task_alter(), I notice the following code.

  if ($root_path == 'blog') {
    $item = menu_get_item('node/add/blog');
    if ($item['access']) {
      $item['title'] = t('Create new blog entry');
      $data['actions']['output'][] = array(
        '#theme' => 'menu_local_action',
        '#link' => $item,
      );
    }
  }
  // Provide a helper action link to the author on the 'blog/%' page.
  elseif ($root_path == 'blog/%' && $router_item['page_arguments'][0]->uid == $user->uid) {
    $data['actions']['output']['blog'] = array(
      '#theme' => 'menu_local_action',
    );
    if (user_access('create blog content')) {
      $data['actions']['output']['blog']['#link']['title'] = t('Post new blog entry.');
      $data['actions']['output']['blog']['#link']['href'] = 'node/add/blog';
    }
    else {
      $data['actions']['output']['blog']['#link']['title'] = t('You are not allowed to post a new blog entry.');
    }
  }

In your case, you should check that $root_path is equal to node/%; in that way you would avoid to do something when the page being shown is the front page. (If node/% doesn't work, then node/%node should.)

I still think that hook_local_tasks_alter() should not be used in this case, as it seems to me that hook_local_tasks_alter() is thought to be used when altering the tabs depends from the page being viewed, as blog_local_task_alter() shows.

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.