If you are using Drupal 6 or higher, a new hook is available called hook_menu_alter() which allows you to alter various properties of menu items that are set by core or other modules.

To use this function, you will need to make an extremely simple custom module to include the code snippet in, which the lesson How to create a simple Drupal 6 module in three easy steps should help with (or if you already have a custom module, simply add the function, adjust the name prefix, and clear the menu cache).

Do not include the opening and closing PHP tags, which are used here only to trigger code highlighting:

/**
 * Implementation of hook_menu_alter().
 * Remember to clear the menu cache after adding/editing this function.
 */
function MODULENAME_menu_alter(&$items) {
  // Removing certain local navigation tabs that are either undesired or need to be custom relocated.

  // Set these tabs to MENU_CALLBACK, so they still register the path, but just don't show the tab:
  $items['node/%node/track']['type'] = MENU_CALLBACK;
  $items['user/%user/track']['type'] = MENU_CALLBACK;
  $items['search/user/%menu_tail']['type'] = MENU_CALLBACK;
  
  // Fully unset these tabs and their paths, don't want them at all. This breaks the path as well:
  unset($items['user/%user/example']);
}

After saving the code snippet in a custom module, clear the menu cache for it to take effect. This can be done by clearing the cache at Administer > Site configuration > Performance, or through helper modules such as Admin Menu (top left icon) or Devel (in the Devel block).

Note that using unset() on a menu item completely removes the path connected with that menu item (for instance, if the menu item being unset had a path of /user/example then that path would now provide a page not found error). Using the unset() method should only be used to completely remove menu items and their paths from a site.

This method should be able to remove most menu tabs, however it cannot remove the View tab. If you need to remove the View tab, you can do so using this alternate technique.

Comments

ressa’s picture

This function works perfectly, but is it possible to hide some tabs for anonymous and registered users, while letting admin view everything and access their paths?

Thanks.

ressa’s picture

With a lot of help (thanks!), I finally got it to work.

This function will hide the view, edit, and track user tabs, whereas admin, or user roles that are granted access, can see them. Follow the directions above to implement it in a module:

// $Id: remove_tabs.module

/**
* Set up a new permission for the module.
* Grant access under admin -> user management -> permissions
*/
function remove_tabs_perm() {
  return array('view hidden tabs');
}

/**
* Implementation of hook_menu_alter().
* Remember to clear the menu cache after adding/editing this function.
*/
function remove_tabs_menu_alter(&$items) {
$items['node/%node/track']['access callback'] = 'user_access';
$items['node/%node/track']['access arguments'] = array('view hidden tabs');

$items['user/%user/view']['access callback'] = 'user_access';
$items['user/%user/view']['access arguments'] = array('view hidden tabs');

$items['user/%user/track']['access callback'] = 'user_access';
$items['user/%user/track']['access arguments'] = array('view hidden tabs');

$items['search/user']['access callback'] = 'user_access';
$items['search/user']['access arguments'] = array('view hidden tabs');
}

To remove the personal contact form tab and form, use the x author module

jonhattan’s picture

I love this solution :)

Kimberley_p’s picture

Exactly what I needed - thanks so much.

mrcniceguy’s picture

Very helpfull,Thank You.

johns996’s picture

Anyone do something like this in Drupal 7? I got the permissions part worked out, but I can't figure out the menu alter part.

function mymodule_permission() 
{
	return array(
		'administer my module' => array(
		'title' => t('view hidden tabs'),
		'description' =>t('Toggle the view of certain drupal admin tabs'),
		),
	);
}
UNarmed’s picture

This looks like exactly what i am looking for, the only problem is i dont have a clue how to use it. I have created and enabled the custom module.

How do i make the view tab on a node invisible for example? I dont get how i target different tabs, if someone could explain this i would be very thankfull.

Regards

marty.true’s picture

I have been using this and it is working awesome. I just tried using it for a sub-tab and it does not remove (hide or unset) the sub-tabs. What am I missing here? Thanks in advance!!

Tafa’s picture

Hello,

Is there any way someone can grant access to the URLS rather than the tabs if a user is granted permission. I want to hide the tabs but I want to use the URLs in another menu I created in a primary menu block. T|he idea is to have users with correct granted permission to be able to modify their content. So far, I managed to get rid of the tabs. But when I do so, users are not granted access to the URLs even though the permissions are set correctly. It took some days to find out about it and it would be more than appreciated if someone could lead me in the right direction for this.
Thanks
T

Tafa’s picture

Problem Solved!
I got my inspiration from here http://drupal.org/node/604850

Phew!

manshi’s picture

it's possible to allow only register user?

gaellafond’s picture

See this patch to add the needed permissions in the Tracker module to disable it:
http://drupal.org/node/762962
This patch has to be apply every time you update the tracker module. It's not as nice as an independent module, but it's much simple.

Weka’s picture

Using the example above I made a custom module to remove the Users tab from search pages. The tabs did disappear; however users are still able to access the search/user path and search for accounts.

Here is the code I used in the module. Did I miss something?

<?php
// $Id: custom_mod.module

/**
* @file
* Custom functions and overrides.
*/
/**
* Implementation of hook_menu_alter().
* Remember to clear the menu cache after adding/editing this function.
*/
function custom_mod_menu_alter(&$items) {
  // Removing certain local navigation tabs that are either undesired or need to be custom relocated.

  // Set these tabs to MENU_CALLBACK, so they still register the path, but just don't show the tab:
  $items['node/%node/track']['type'] = MENU_CALLBACK;
  $items['user/%user/track']['type'] = MENU_CALLBACK;
  $items['search/user']['type'] = MENU_CALLBACK;
 
  // Fully unset these tabs and their paths, don't want them at all. This breaks the path as well:
  unset($items['search/user']['type']);
}
RodrigoBalest’s picture

Maybe I'm wrong, but I think you should use

unset($items['search/user']);

instead of

unset($items['search/user']['type']);
Gomez_in_the_South’s picture

The following worked for me in Drupal 6 (in a module as described above) :

unset($items['search/user/%menu_tail']);
netentropy’s picture

how do you find the values for all of the $items variables?

ñull’s picture

Using %menu_tail was the only way to reliably hide the search tabs. My function looks like this now:

function removetabs_menu_alter(&$items) {
  $items['search/user/%menu_tail']['type'] = MENU_CALLBACK;
  $items['search/node/%menu_tail']['type'] = MENU_CALLBACK;
  $items['search/search_files_attachments/%menu_tail']['type'] = MENU_CALLBACK;
  }
steinmb’s picture

I'll also experienced this, also had a quick look at http://api.drupal.org/api/drupal/modules--search--search.module/function... that also confirm this. I'll take my changes and change the documentation.

Stein Magne
http://smbjorklund.no

anavrin’s picture

Hi there,

I had a simillar problem ...
Your solution may work - but not always - it didn't work for me.
I needed to hide tab admin/people/permissions - for a user who had some administrative permissions and show it for a real admin (uid=1).

Thus in mymodule_menu_alter I added:

if ($user->uid!=1)
{
// $items['admin/people/permissions']['type'] = MENU_CALLBACK;
}

Your solution work only when I always was flushing all caches :-) which is obviously not acceptable for efficiency reasons.

(I put drupal_flush_all_caches into mymodule_init() function. - than it worked - but I couldn't leave it like this).

Instead of this I had to do it like this:

in mymodule_menu_alter I added:

function amod_menu_alter(&$items) {

	$items['admin/people/permissions']['access callback'] = 'mychecker';

}
function mychecker() {
global $user;
if ($user->uid!=1) {
return false;
}
return true;
}
}

I also had to use drupal_flush_all_caches in the mymodule_init() function but only once. Then I comment it out.

Now it works fine. Hope it will be useful to someone ...

regards,
anavrin

hwasem’s picture

We are using LDAP authentication which populates all of the information in our user profile's edit tab. I want the users to add "About Me" information which I have added via Content Profile on it's own tab.

I'm attempting to remove the User profile's Edit tab for everyone but Site Admin and SuperAdmin roles. I first tried Ressa's (11/12/09) code:

/**
 * Allow Profile edit tab for permission 'profile edit tab' 
 */
//Add new permission for module
function mymodule_perm() {
  return array('profile edit tab'); 
}

// Implementation of hook_menu_alter().
  function mymodule_menu_alter(&$items) {
    $items['user/%user/edit']['access callback'] = 'user_access';
    $items['user/%user/edit']['access arguments'] = array('profile edit tab');
  }

I see the new permission showing up and have granted access to the appropriate roles. I no longer see the Edit tab for all users, including my own (member of both SuperAdmin and Site Admin role). I have cleared cache via /admin/settings/performance many times and even rebuilt permissions.

I also tried to use anavrin's method by calling my UID directly instead of adding a new permission and the Edit tab is still not showing for me. The code I used is as follows where ### is my UID:

function mymodule_menu_alter(&$items) {
  $items['user/%user/edit']['access callback'] = 'mychecker';

}

function mychecker() {
  global $user;
  if ($user->uid!=###) {
   return false;
  }
  return true;
}

Again I cleared cache via /admin/settings/performance and I can't see the edit tab. I even tried making function mychecker(){ return true;} and the tab didn't show for me. If I remove the module, the tab returns just fine, so there isn't a problem with the tab's path. It just seems like it is all or nothing.

Am I using the correct code and access options? Any advice is much appreciated!

nickrice’s picture

If you don't want to get your hands dirty in code you might find that the Tab Tamer module (http://drupal.org/project/tabtamer) does what you want.

rajmataj’s picture

I found TabTamer almost useful but ultimately a confusing UI to accomplish my goal, which was to remove the "Revision Information" tab in Drupal 7's admin theme because none of the users on the site would actually use it when editing content.

I found using Jammer was really helpful. Install it, enable the submodule 'Content Form Jammer' and go to admin/config/user-interface/jammer to select items to disable tabs you don't want to use or see.

bobmurdoch’s picture

@bjraines:
print_r($items) inside of hook_menu_alter, clear your menu cache and you'll get an array dump of all of them. View source in your browser to see them with nicer formatting.

anthonylindsay’s picture

You can refine that verbose output with

print_r(array_keys($items));

which makes it much easier to see what menu items there are.

And even refine it further with something like print_r(array_keys($items['user']));

pinkonomy’s picture

I tried this with drupal 7 but it doesn't work.Specifically it doesn't remove the tab,it only prevents access to the path.
I want the opposite,to remove the tab but have access to the path.Here is the code:

function custom_menu_alter(&$items) { 

$items['users/%user/points']['type'] = MENU_CALLBACK;
$items['users/%user/hybridauth']['type'] = MENU_CALLBACK;

}
mrcniceguy’s picture

Here is how i did it in Drupal 7.
i was hidding tabs on node Page, so it is the same as hidding on users page.


/**
 *Hook_permission implementation
 */
function ims_permission()
{
	return array(
		'view tabs on node' => array(
		'title' => t('View Hiddent Tabs on node'),
		'description' =>t('Allow them to see the tabs on user page'),
		),
	);
}


/**
* Implementation of hook_menu_alter().
*
*/
function ims_menu_alter(&$items) {
$items['node/%node/view']['access callback'] = 'user_access';
$items['node/%node/view']['access arguments'] = array('view tabs on node');

$items['node/%node/edit']['access callback'] = 'user_access';
$items['node/%node/edit']['access arguments'] = array('view tabs on node');

}
gusantor’s picture

hello, any clue about how to get this to work for node/%node/workflow menu ?

I'm using workflow fields

for testing, I've implemented

function my_module_menu_alter(&$items){
$items['node/%node/workflow']['access callback'] = '_my_function';
}

function _my_function(){
return true;
}

but this wont to work, the menu just disappear, even when I return true in _my_function

thanks

gusantor’s picture

I tried also, but won't work either (% instead of %node)

function my_module_menu_alter(&$items){
$items['node/%/workflow']['access callback'] = '_my_function';
}

function _my_function(){
return true;
}

and when I do dpm($items), I can't find it, all references point to admin/config/workflow, none to node/*/workflow

please any hint ???