I have a View that is a primary tab on the user profile page. The user profile tabs look like this view | edit | menu-item-to-hide. If the person viewing the page is does not have role of admin or the owner of the profile page then they should not see the tab.

I assume that I use hook_menu_alter() but I'm not sure what the code should be.

3 Answers 3


I created a mini module called helper.

In helper.info I put

name = "Helper"
description = "Provides custom support functions."
core = "7.x"

First we need to get the helper_menu_alter() to be called after views_menu_alter so we use hook_module_implements_alter to pull the value of our module in the array and put it back in which will always be done at the end of the array.


function helper_menu_alter(&$items){
  $items['user/%/workbench']['access callback'] = 'helper_access';
  $items['user/%/workbench']['access arguments'] = array(1);
  $items['user/%/workbench/drafts']['access callback'] = 'helper_access';
  $items['user/%/workbench/drafts']['access arguments'] = array(1);
  $items['user/%/workbench/needs-review']['access callback'] = 'helper_access';
  $items['user/%/workbench/needs-review']['access arguments'] = array(1);

 * Helper access callback.
function helper_access($uid) {
  if ($uid) {
    if ($GLOBALS['user']->uid == $uid || user_access('view all unpublished content')) {
      return TRUE;
  return FALSE;

function helper_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'menu_alter') {
    // Move helper_menu_alter() to the end of the list. module_implements()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['helper'];
    $implementations['helper'] = $group;
  • You shouldn't change your weight to 99, in d6 this was a big problem where every module kept trying to one up each other. At the very least you should set your weight to whatever views is + 1. Also this is why hook_module_implements_alter was added in d7. To avoid every module trying to get a higher weight.
    – ericduran
    Commented Jun 23, 2011 at 4:38
  • 1
    You shouldnd check if user has uid 1. user_access for user1 is always TRUE
    – milkovsky
    Commented Jun 25, 2013 at 5:28

Hook_menu_alter is called when the menu is being rebuild so you shouldn't use it for these situations.

Normally you should set the permission on your page view to only allow the roles you want to see that view. The menu system will handle hidding the tab for you when the user doesn't have the right permission.

The one thing that's weird is that you want to restrict on a role and if the user is viewing his own profile. In this case you do want to use hook_menu_alter but not to hide the menu tab but instead to replace the access callback with your own.

In your custom access callback you want to do something like http://api.drupal.org/api/drupal/modules--user--user.module/function/user_view_access/7

So essentially you want to do the logic on the access callback not on the hook_menu_alter.

You're going to run into issues with weights because I'm sure views run last.

To work around this you should implements hook_module_implements_alter to designate your module to run after views only for the hook_menu_alter hook.

This doesn't required any weight changes and it helps resolve the problem where you might want your module to run before views in certain situations, yet after it in a different situation.

  • i wrote this on a mobile device, so this answer could use some cleanup.
    – ericduran
    Commented Jun 23, 2011 at 1:12
  • I had already figured out using the user_view_access() but I couldn't find a way to alter Views which was called by hook_menu_alter() after the callback in my module was. I needed to alter the system table in the database first.
    – Adam S
    Commented Jun 23, 2011 at 3:58
  • 1
    Yes, you're module needs to have a higher weight than views. Also you can get around this by implement hook_module_implements_alter. Which will let you designate your module to be ran after views. Instead of changing the system table.
    – ericduran
    Commented Jun 23, 2011 at 4:33

Easiest way is to write custom Access Callback with Views Access Callback module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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