Last updated August 26, 2009. Created by budda on June 13, 2006.
Edited by ronald_istos, Keyz. Log in to edit this page.

Both Drupal core as well as various modules add tabs to pages that are not needed for general users, or not needed at all. You may wish to link to the page in a different way, as some users don't understand that they can click on the tab above a node.

Method for Drupal 4.7.x and Drupal 5

In versions of Drupal prior to 6, there was not a way to alter the hook_menu() generated tabs from code, so the function illustrated on this page will find and strip out a tab based on its name. As of Drupal 6, there is now the hook_menu_alter() function, which allows you to alter various properties of menu items that are set by core or other modules. If you are using Drupal 6, you should consider using hook_menu_alter instead, which is more exact, and is simpler/more efficient. One thing that hook_menu_alter cannot do that this page's method can is remove the "View" tab (if you have reason to remove the View tab, you can do so with this technique, and use hook_menu_alter for the rest of your tab removals).

Step 1 of 2

Locate your theme's template.php file. If one doesn't exist, create an empty one. This is where you can place customization PHP code.

Step 2 of 2

Custom functions placed in the themes template.php file should begin with the theme name. In the code snippet below replace "yourthemename" with the actual name of your theme, such as "garland".

You may already have a '_phptemplate_variables' function defined depending on what theme you are using, if so do not include the function again from the snippet below.

<?php
function _phptemplate_variables($hook, $vars = array()) {
  if (
$hook == 'page') {
   
yourthemename_removetab('address book', $vars);
   
// add additional lines here to remove other tabs.
 
}
  return
$vars;
}
function
yourthemename_removetab($label, &$vars) {
 
$tabs = explode("\n", $vars['tabs']);
 
$vars['tabs'] = '';
  foreach (
$tabs as $tab) {
    if (
strpos($tab, '>' . $label . '<') === FALSE) {
     
$vars['tabs'] .= $tab . "\n";
    }
  }
}
?>

The tab removal work is done in the yourthemename_removetab() function, pass in a plain text tab label, along with the PHPTemplate variables, and the function will remove the tab.

In the above example snippet the 'address book' tab added by the eCommerce package is removed from the user's profile page.

Notes

  • Call yourthemename_removetab('tab name', $vars); for each tab you wish to remove.
  • No other modules need to be installed to use this.
  • If you need more exact control of which page on the site to affect (since different tabs might share the same name), you can wrap the removetab function with conditions that check the URL path arguments.

Method for Drupal 6

As mentioned in the introduction, generally you should consider using Drupal 6's hook_menu_alter to remove tabs instead. However if you need to use this page's tab removal method, the below code is adapted for use in Drupal 6. The notes and info in the above steps still apply in the same way.

First either add the first code snippet as shown, or else merge it with your current preprocess_page() function in template.php (you cannot have two of the same function, so look for preprocess_page). In both code snippets, change all instances of "yourthemename" to the name of your current theme, and do not include the opening and closing PHP tags.

<?php
function yourthemename_preprocess_page(&$vars) {
 
// Remove undesired local task tabs.
  // This first example removes the Users tab from the Search page.
 
yourthemename_removetab('Users', $vars);
}
?>

Then add this function "outside" of the yourthemename_preprocess_page() function:

<?php
// Remove undesired local task tabs.
// Related to yourthemename_removetab() in yourthemename_preprocess_page().
function yourthemename_removetab($label, &$vars) {
 
$tabs = explode("\n", $vars['tabs']);
 
$vars['tabs'] = '';
  foreach (
$tabs as $tab) {
    if (
strpos($tab, '>' . $label . '<') === FALSE) {
     
$vars['tabs'] .= $tab . "\n";
    }
  }
}
?>

After saving template.php, you may need to rebuild the theme registry before your changes will take effect. This can be done by clearing the cache at Administer > Site configuration > Performance, or through helper modules you likely have such as Admin Menu (top left icon) or Devel (in the Devel block).

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

This method works for me and is cleaner (IMO) and more performant than the regexp method:
Tabs are the default way of rendering menu items of type MENU_LOCAL_TASK or MENU_DEFAULT_LOCAL_TASK. So, there is a theming function theme_menu_local_task() in menu.inc that renders them. If you override it in your theme, you can skip certain tabs by simply returning the empty string as their rendered html:
This function would go into template.php in your theme.

<?php
function phptemplate_menu_local_task($mid, $active, $primary) {
 
//Check which tab is being rendered
 
$item = menu_get_item($mid);
 
//Remove core search tab
 
if ($item['path'] == 'search/node') {
    return
'';
  }
 
//The rest is copied from theme_menu_local_task()
 
if ($active) {
    return
'<li class="active">'. menu_item_link($mid) ."</li>\n";
  }
  else {
    return
'<li>'. menu_item_link($mid) ."</li>\n";
  }
}
?>

This example removes the core search tab.

For example,

if ($item['path'] == 'user') {
    return '';
  }

does not remove the Log In tab.

The path to the login tab is 'user/login' for me (4.7). If you use that it should work. It's the menu item's path, not the path of the request that should be checked.

That did it in 5.7 too.

Customized it to avoid the Tabs on search-subsites (if you search for "dog" the tab path is "/search/node/dog" and it doesn't work.
I avoided regexp and used str_replace due perfomance reasons.

<?php
function phptemplate_menu_local_task($mid, $active, $primary) {
 
//Array with Tabs to be removed
 
$disabled_tabs = array('search/user' , 'search/node');
 
//Check which tab is being rendered
 
$item = menu_get_item($mid);
  foreach (
$disabled_tabs as $tab) {
      if (
substr($item['path'],0,strlen($tab))==$tab) {
          return
'';
      }
  }
 
//The rest is copied from theme_menu_local_task()
 
if ($active) {
    return
'<li class="active">'. menu_item_link($mid) ."</li>\n";
  }
  else {
    return
'<li>'. menu_item_link($mid) ."</li>\n";
  }
}
?>

My task was to combine profilesearch module with default search module.
Here is the code. I keep tab title, but redirect user to another url (profilesearch/search_string).
Drupal 5.10.

<?php
function phptemplate_menu_local_task($mid, $active, $primary) {
 
//Check which tab is being rendered
 
$item = menu_get_item($mid);
 
//Remove core search tab
 
if (stristr ($item['path'], 'search/user')) {
   
$search_string=substr($item['path'], strpos($item['path'],'search/user/')+12 );
    return
'<li><a href="/profilesearch/'.$search_string.'">'.$item['title']."</a></li>\n";
  }
 
//The rest is copied from theme_menu_local_task()
 
if ($active) {
    return
'<li class="active">'. menu_item_link($mid) ."</li>\n";
  }
  else {
    return
'<li>'. menu_item_link($mid) ."</li>\n";
  }
}
?>

I had a similar problem with drupal 6, and I couldn't get your fix to work.

What I did in stead was to add a new submit function to the search forms which makes a redirect to my custom search module (called 'userfinder') - heavily inspired by how the search module redirects to search/node.

This way the results of my own search module is presented first to the user. At first I wanted to remove the 'Content' and 'User' search tabs as well, and followed vijaythummar suggestion which worked perfectly. I ended up deciding to keep them as 'back-up' facilities though.

So in my userfinder.module I have:

/**
  * Implementation of hook_form_alter().
  */
   function userfinder_form_alter(&$form, &$form_state, $form_id) {
     //This code gets called for every form Drupal build; so be sure to bail out quick
     // if the desired form is not present
     if ($form_id == 'search_block_form' || $form_id == 'search_form') {
       //Redirect to our own usersearch
       $form['#submit'][] = 'userfinder_search_submit';
     }
   }
   function userfinder_search_submit($form, &$form_state) {
     $form_id = $form['form_id']['#value'];
     $args = trim($form_state['values'][$form_id]);
     if ($args && $args != '') {
       $form_state['redirect'] = 'search/userfinder/'. $args;
     }
   }

Remove tabs in Drupal 7, I did this in template.php:

<?php
function yourthemename_preprocess_page(&$vars, $hook) {
 
// Removes a tab called 'Reviews, change with your own tab title
 
yourthemename_removetab('Reviews', $vars);
}
// Remove undesired local task tabs.
// Related to yourthemename_removetab() in yourthemename_preprocess_page().
function yourthemename_removetab($label, &$vars) {
 
// Remove from primary tabs
 
$i = 0;
  if (
is_array($vars['tabs']['#primary'])) {
    foreach (
$vars['tabs']['#primary'] as $primary_tab) {
      if (
$primary_tab['#link']['title'] == $label) {
        unset(
$vars['tabs']['#primary'][$i]);
      }
      ++
$i;
    }
  }
 
// Remove from secundary tabs
 
$i = 0;
  if (
is_array($vars['tabs']['#secundary'])) {
    foreach (
$vars['tabs']['#secundary'] as $secundary_tab) {
      if (
$secundary_tab['#link']['title'] == $label) {
        unset(
$vars['tabs']['#secundary'][$i]);
      }
      ++
$i;
    }
  }
}
?>

Morningtime, a digital agency
Drupal services, web development, project management.

thanks! this solution works fine for D7

There's another easy to use code snippet for D7 at http://drupal.org/node/1007226#comment-4472056.

Small Typo — here is the fixed version for Drupal 7:

<?php
function yourthemename_preprocess_page(&$vars, $hook) {
 
// Removes a tab called 'Reviews, change with your own tab title
 
yourthemename_removetab('Reviews', $vars);
}
// Remove undesired local task tabs.
// Related to yourthemename_removetab() in yourthemename_preprocess_page().
function yourthemename_removetab($label, &$vars) {
 
// Remove from primary tabs
 
$i = 0;
  if (
is_array($vars['tabs']['#primary'])) {
    foreach (
$vars['tabs']['#primary'] as $primary_tab) {
      if (
$primary_tab['#link']['title'] == $label) {
        unset(
$vars['tabs']['#primary'][$i]);
      }
      ++
$i;
    }
  }
 
// Remove from secondary tabs
 
$i = 0;
  if (
is_array($vars['tabs']['#secondary'])) {
    foreach (
$vars['tabs']['#secondary'] as $secondary_tab) {
      if (
$secondary_tab['#link']['title'] == $label) {
        unset(
$vars['tabs']['#secondary'][$i]);
      }
      ++
$i;
    }
  }
}
?>

--
wOOge | adrianjean.ca

hey thanks this is just what i needed... only prob is on when using overlay i get this error "Notice: Undefined index: #primary in seven_removetab()" and the tab isn't removed... how would i fix that problem.

For some reason, if I try and remove the 'Content' tab on the Search page, the styling of the tabs gets messed up (there are no more tabs, just a real plain looking bulleted list!). I haven't investigated the code much yet, but looks like there is something special about the first tab in a series of tabs (other tabs that aren't first seem to get cut just fine).

You are correct, this method does not work any time it is the first tab, and thus this handbook method is poorly coded. What happens is the tabs get broken up by newlines, so as a basic example, tabs are the string: <ul><li>first item</li><li>second item</li></ul>

Which then gets divided into an array
1. <ul><li>first item</li>
2. <li>second item</li>
3. </ul>

So if you delete the first tab item, it also deletes the first <ul>, so the list breaks! Hope this helps others, I'm sure there are good methods somewhere in the comments, I just haven't looked through all of them :)

Please note that the simple method for removing the User Search functionality is to disable the permission "access user profiles" for the role which you don't want seeing it. You may only be seeing this because you're logged in as an administrator.

I needed to remove tabs in search & that IMCE file management tab in user accounts. Used strpos in php5, sounds like its fastest.
This would go in template.php still.

<?php
/*
* Remove search users tab & the file upload tab for all users.
*/
function phptemplate_menu_local_task($link, $active = FALSE) {
  if (
strpos($link,'search') ) {
    return
'';
  }    else if (
strpos($link,'imce') ) {
    return
'';
  } else {
      return
'<li '. ($active ? 'class="active" ' : '') .'>'. $link ."</li>\n";
  }
}
?>

Thanks for that!

I was trying to remove the 'Request new password' tab on the user login form and for some reason it wouldn't disappear until I realise that I needed to match the case of the text (capital R). Tada! It works!

Here what I have used to remove unnecessary tabs in drupal6.

<?php
function phptemplate_preprocess(&$variables, $hook) {
  if(
$hook == 'page') {
   
yourthemename_removetab('File browser', $variables);
  }
  return
$variables;
}
function
yourthemename_removetab($label, &$vars) {
 
$tabs = explode("\n", $vars['tabs']);
 
$vars['tabs'] = '';
  foreach(
$tabs as $tab) {
    if(
strpos($tab, '>' . $label . '<') === FALSE) {
     
$vars['tabs'] .= $tab . "\n";
    }
  }
}
?>

Regards,
vijay thummar

Thanks & Regards,
Vijay Thummar

Thank you! I've been looking everywhere for a way to do this.

That actually works! Was looking for ages for a solution like that. Thanks :)

Could you post some code to:

- Edit existing tabs.
- Only delete/edit tabs from certain pages and not from all pages.

I would be really grateful! Thanks in advance!

if you want this to hide tabs only in certain pages you might want to check the URL via the arg() function. For example, to hide some tabs only in the user profile pages:

replace

<?php
if($hook == 'page')
?>

with

<?php
if($hook == 'page' && arg(0)=='user')
?>

I am not sure if this is very efficient, or foolproof, but it's working for me so far:

<?php
/**
* If the user isn't an admin, or the original administrative user,
* remove the "edit" tab for the "note" nodes in the my_garland theme.
*/
function phptemplate_preprocess(&$variables, $hook) {
    global
$user;
    if(
$hook == 'page' && !in_array('admin',array_values($user->roles)) && $user->uid != 1){
       
$nid = str_replace('page-node-','',$variables['template_files'][1]);
       
$node = node_load($nid);
        if(
$node->type == 'note'){
           
my_garland_removetab('Edit', $variables);
        }
    }
    return
$variables;
}
?>

I presume we have to change 'page' to a different content type if it applies. I changed youthemename to my theme name. With those changes (and removing the php tags) I could not get the "View" tab to go away..

No it has nothing to do with the Page content type. Page here refers to page.tpl.php
You can read more about it here http://drupal.org/node/223430

could not remove "Log in" tab in Drupal 6 using any method specified here

This forum post helped me solve my tabs problem. I think that the example above works as well, I just didn't realize that I had 2 preprocess functions!

http://drupal.org/node/379792

I would like to remove backlinks tab but all I tried doesn't function.
Can you help me?
Is it correct "backlinks" name to remove backlinks tab?

Check your view. I believe it has an option to turn off the backlinks tab.

Views in D7 sure does remove that tab, and with no extra coding.

if you want this to hide tabs only in certain pages you might want to check the URL via the arg() function. For example, to hide some tabs only in the user profile pages:

replace

<?php
if($hook == 'page')
?>

with

<?php
if($hook == 'page' && arg(0)=='user')
?>

I have different types of users. So i have different categories in profile. Now based on the user type I need to display certain tabs. Is there a easy way to do it or that i need to write a query to extract value from profile_values table and add the appropriate conditions in the proprocess funtion...

Based on this, and another comment, here's what's working for me to remove ALL tabs, only on user pages, placed in my template.php file:

<?php
function phptemplate_preprocess(&$variables, $hook) {
  if(
$hook == 'page' && arg(0)=='user') {
   
$variables['tabs'] = "";
  }
  return
$variables;
}
?>

I needed this because I created a custom menu for different types of users, and created additional pages that start with /user/ in the url that I wanted any (if any) tabs to match. The menu I created is serving as the tabs in my particular case and has removed any confusion.

Worlds to explore. Worlds to create.
Blog: http://www.christopherstevens.cc/blog
Twitter: http://www.twitter.com/owntheweb

This works for removing tabs on the registration page:

<?php
function phptemplate_preprocess(&$variables) {
  if(
arg(1)=='register') {
   
$variables['tabs'] = "";
  }
  return
$variables;
}
?>

Sorry to post again...
I am not sure if this is very efficient, or foolproof, but it's working for me so far:

<?php
/**
* If the user isn't an admin, or the original administrative user,
* remove the "Edit" tab for the "note" nodes in the my_garland theme.
*/
function phptemplate_preprocess(&$variables, $hook) {
    global
$user;
    if(
$hook == 'page' && !in_array('admin',array_values($user->roles)) && $user->uid != 1){
       
$nid = str_replace('page-node-','',$variables['template_files'][1]);
       
$node = node_load($nid);
        if(
$node->type == 'note'){
           
my_garland_removetab('Edit', $variables);
        }
    }
    return
$variables;
}
?>

That works fine, and so does the method for Drupal 6 using menu_alter. The problem im having is I cant disable the functionality, only the tab.

For example. I have Node Gallery installed, I created an "Upload Images" tab, but of course it appears on all standard pages using MENU_LOCAL_TASK, not just the gallery pages. I can remove it easily enough using the above method for node type blog, page, story etc...but the user can still type in the direct URL and get the functionality - http://www.mydomain.com/node/22/upload...is a book node, without blocking actual functionality a user can upload images into book nodes, rather than the gallery itself!!! eeek.

I either need a way to make sure this tab only works with certain modules - in this case the node gallery module, or i need to block direct url access to the upload page on every other part of the site apart from the gallery...

It would be nice if the "user module" permissions group had an 'edit own account' checkbox, and have any module that wants to put a tab under My Account be required to put their own checkboxes here.

To be practical (since that suggestion isn't trivial), and since my site just disallows users to change email address or password, perhaps give us a way to hide certain widgets ("Account information" in my case).

I used this to remove the 'Edit' tab for the role 'customer' and disable access to the 'Edit' page altogether with the Path Access module.

I also have two roles, 'partner' and 'customer', with different Content Profiles, so I removed the 'partner' Content Profile tab when admin or editor are viewing a 'customer' role user, and vice versa.

Under Path access for the 'customer' role I added:

Access every page except the listed pages:
user
user/*/edit

To remove the 'Edit' tab for the 'customer' role only, and hide the "wrong" Content Profile from admin and editor:

<?php
// Remove 'Edit' tab from the 'customer' role,
function phptemplate_preprocess(&$variables, $hook) {
  global
$user;
 
$user_obj = user_load(arg(1));
  if(
$hook == 'page' && (in_array('customer', $user->roles)) && $user->uid != 1) {
   
THEMENAME_removetab('Edit', $variables);
  }
 
// User profile role viewed is 'customer', hide Content Profile tab('Partner') from admin and editor
 
elseif($hook == 'page' && ($user_obj->roles[4])) {
   
THEMENAME_removetab('Partner', $variables);
  }
 
// User profile role viewed is 'partner', hide Content Profile tab('Customer unit') from admin and editor
 
elseif($hook == 'page' && ($user_obj->roles[6])) {
   
THEMENAME_removetab('Customer unit', $variables);
  }
  return
$variables;
}
function
THEMENAME_removetab($label, &$vars) {
 
$tabs = explode("\n", $vars['tabs']);
 
$vars['tabs'] = '';
  foreach(
$tabs as $tab) {
    if(
strpos($tab, '>' . $label . '<') === FALSE) {
     
$vars['tabs'] .= $tab . "\n";
    }
  }
}
?>

if you wanna remove each an devery tab from everywhere in the website, for every user (which, i needed for a weird reason) do this:

<?php
function yourthemename_preprocess_page(&$vars) {
 
// Remove all local task tabs, from everywhere on the site, for all users.
$vars['tabs'] = "";
}
?>

--
Kinshuk

Does this also work when you want to remove the reply link from comments?

Dose anyone know how i would go about removing tabs from certain modules? Basicaly i am trying to remove tabs in the admin section that i feel might confuse the end user.

Ah the post by vijaythummar got me the desired result =] muchoz thanks!

I'm getting a rogue, unwanted Attendees tab on my Ubercart product pages.

Anyone know of a clean way of removing this?

Thanks!
Stan

You can use HOOK_MENU_ALTER to change the access of menu.

Thanks,
Vijay Thummar
CIGNEX Technologies Pvt Ltd

Thanks & Regards,
Vijay Thummar

You have to create a new module but wat has to be the content in it?

And where does the code of the hook menu alter has to come in wich directory i
have to create these files?

I'm a little bit stuck with the tabs.

I can program with PHP but i just don't know where to place the costum module and other code.

Regards Nick

I have the code below to remove tab from user not in certain roles but it's not working. Is there something I'm missing?

<?php
function phptemplate_menu_local_task($link, $active = FALSE) {
if (
arg(0) == 'user' ) {
   
$nid = arg(1); //node id
   
$user_id = user_load(array('uid'=>$nid));
      if (
$user_id->roles[7] == buyer or $user_id->roles[9] == dealer or $user_id->uid == 1 ) {
        return
'<li '. ($active ? 'class="active" ' : '') .'>'. $link ."</li>\n";
      } else if (
strpos($link,'Shop') ) {
         return
'';
      }else if (
strpos($link,'Biz') ) {
         return
'';
         }
  }
}
?>

I had the same problem here,
just use the tab tamer module that you can download here on the site.

If the modules doesn't work for you,

then you have to go to the module and edit this rule in the tabtamer.module file:

Search for this rule in the module and delete it!:

if (is_array($val) && $val['type'] == MENU_DEFAULT_LOCAL_TASK) {

AND REPLACE IT BY THIS RULE:

if (is_array($val) && ($val['type'] == MENU_DEFAULT_LOCAL_TASK || empty($val['type']))) {

It can be you need to empty your cache but probably not.

Regards

Hello nickse88

thank you very much for sharing ! I had to empty caches after patching the module !

Sepp

I am not a php programmer and I've added this code below to remove the tabs but it's not working. I copied it to the end of the existing code. I've also tried it without both the

<?php
at the beginning
and the 
?>
at the end. Can anyone tell me what I'm doing wrong please?

<?php
function phptemplate_preprocess(&$variables, $hook) {
  if(
$hook == 'page' && arg(0)=='user') {
   
$variables['tabs'] = "";
  }
  return
$variables;
}
?>

Why needing to do this at all to control the menu local tasks' tabs is beyond me. They are not accessible with Tab Tamer, Local Task Blocks or anything else I've found so far. I'd love to be able to keep some of the tabs but I can't do anything with them. I'm just so frustrated with them that now I just want them gone.

Thank you for your help. It is appreciated.

Hélène

It is also possible to do this via hook_menu_local_tasks_alter(). Actually, that would be my recommendation over a preprocess_page call. This hook specifically handles the kind of menu modifications we're trying to accomplish on this page.

...and, an example; in this case, I'm removing the 'View' tab from 'note' type nodes:

<?php
/**
* Implements hook_menu_local_tasks_alter().
*/
function fn_notes_menu_local_tasks_alter(&$data, $router_item, $root_path) {
 
// For note nodes, remove the 'View' tab when viewing the node.
 
foreach ($router_item['page_arguments'] as $key => $argument) {
    if (
is_object($argument) && $router_item['page_arguments'][$key]->type == 'note') {
      foreach (
$data['tabs'][0]['output'] as $key => $value) {
        if (
$value['#link']['path'] == 'node/%/view') {
          unset(
$data['tabs'][0]['output'][$key]);
        }
      }
    }
  }
}
?>

__________________
Gittip | Work: Midwestern Mac, LLC | Personal: Life is a Prayer.com

Thank you! This worked beautifully.
Here's my adaptation, which has an additional conditional to fix an error if there is no "type" property on a page argument.

<?php
/**
* Implements hook_menu_local_tasks_alter().
*/
function mymodule_menu_local_tasks_alter(&$data, $router_item, $root_path) {
 
// For EOFA nodes, remove the 'Manage registrations' tab
  // because we want registrations managed through Program Display nodes.
  // Because both content types have links back to a program (product with
  // a registration entity), they both have tabs to manage the associated
  // registrations (commerce_registration module is responsible for this)
 
foreach ($router_item['page_arguments'] as $key => $argument) {
    if (
is_object($argument) && isset($router_item['page_arguments'][$key]->type) && $router_item['page_arguments'][$key]->type == 'eofa') {
      foreach (
$data['tabs'][0]['output'] as $key => $value) {
        if (
$value['#link']['page_callback'] == 'commerce_registration_registration_page') {
          unset(
$data['tabs'][0]['output'][$key]);
        }
      }
    }
  }
}
?>

I modified the above to allow either removal or rename of multiple tabs. Just modify the $nodes array in the function. First dimension is content type name, second is key=path, value=renamed value. Leaving value blank removes the tab.

<?php
function YOURTHEME_menu_local_tasks_alter(&$data, $router_item, $root_path) {
   
$nodes = array(
       
'page'    =>    array(
           
'node/%/view'    =>    'Renamed View'
       
)
    );
    foreach (
$router_item['page_arguments'] as $key => $argument) {
        if (
is_object($argument) && array_key_exists( $router_item['page_arguments'][$key]->type, $nodes )) {
            foreach(
$nodes[$router_item['page_arguments'][$key]->type] as $path => $new_title ) {
                foreach (
$data['tabs'][0]['output'] as $key => $value) {
                    if (
$value['#link']['path'] == $path) {
                        if( !
$new_title ) {
                            unset(
$data['tabs'][0]['output'][$key]);
                        } else {
                           
$data['tabs'][0]['output'][$key]['#link']['title'] = $new_title;
                        }
                    }
                }
            }
        }
    }
}
?>

With the Fusion theme, HTML tags are added around tabs in pre-processing if $tabs is anything but empty.

My fix was to check that a tab exists:

<?php
function bali_removetab($label, &$vars) {
 
$tabs = explode("\n", $vars['tabs']);
 
$vars['tabs'] = '';
  if (
$tabs)
  {
      foreach (
$tabs as $tab) {
        if (
strpos($tab, '>' . $label . '<') === FALSE) {
          if (
$tab) $vars['tabs'] .= $tab . "\n";
        }
      }
  }
}
?>

—Matt

$vars['tabs'] = preg_replace('/<li.*Personal Information<\/a><\/li>/', '', $vars['tabs']);

And this let's me get rid of what I want, without having to worry about the mark up so much. Works like a charm!

PS - you can make a little function for multiples, or make a longer regex statement. Tabs are some of the hardest darn things to get rid of!

Nothing unreal exists.

http://drupal.org/project/tabtamer this best way for your wanted.
composition hidden and permission necessary given with the tabs-hidden-action.

Thanks to the developer of this module.

You saved me

My task was to remove Invoice and other tabs for the logistic user. He takes care of shipping, and doesn't need to know anything else.

I just had an if statement as follows:

global $user;
  if(strtolower($user->name) == "logistic"){
    mytheme_removetab('Invoice', $vars);
    mytheme_removetab('Edit', $vars);
    mytheme_removetab('Payments', $vars);
    mytheme_removetab('Log', $vars);
  }

Notice if you use the locale module, the labels (ie Invoice, Edit, and so on) have to match the translations in the user's language

To alter a local task in Drupal 7 in a module you have to first invoke hook_theme_registry_alter and implement your own version of theme_local_tasks.

Here's an example I used with the User Relationships module to alter the 'Relationships' tab title to 'Connections'

<?php
function MYMODULE_custom_theme_registry_alter(&$theme_registry) {
  if (!empty(
$theme_registry['form_element'])) {
   
// Menu local tasks
   
$theme_registry['menu_local_tasks']['function'] = MYMODULE_local_tasks';
  }
}
?>

<?php
function MYMODULE_local_tasks(&$variables) {
 
$output = '';
  if (!empty(
$variables['primary'])) {
   
// Loop through local tasks and alter
   
foreach($variables['primary'] as $key => $link) {
      if(
$link['#link']['path'] == 'user/%/relationships') {
       
$link['#link']['title'] = 'Connections';
      }
     
$variables['primary'][$key] = $link;
    }
   
$variables['primary']['#prefix'] = '<h2 class="element-invisible">' . t('Primary tabs') . '</h2>';
   
$variables['primary']['#prefix'] .= '<ul class="tabs primary">';
   
$variables['primary']['#suffix'] = '</ul>';
   
$output .= drupal_render($variables['primary']);
  }
  if (!empty(
$variables['secondary'])) {
   
$variables['secondary']['#prefix'] = '<h2 class="element-invisible">' . t('Secondary tabs') . '</h2>';
   
$variables['secondary']['#prefix'] .= '<ul class="tabs secondary">';
   
$variables['secondary']['#suffix'] = '</ul>';
   
$output .= drupal_render($variables['secondary']);
  }
  return
$output;
}
?>

Agile Collective | http://agilecollective.com

Simply naming the function properly will get it picked up by the theme registry on cache clear. The naming format is THEMENAME_menu_local_tasks. If you want to name it something else, then that's when you would use the relevant snippet for that above.

WizOne Solutions - http://www.wizonesolutions.com - Drupal module development, theme implementation, and more
Fill PDF Service - http://fillpdf-service.com - Hosted solution for Fill PDF

Note that with locale module :

yourthemename_removetab('Users', $vars);

is :

yourthemename_removetab(t('Users'), $vars);