Drupal 6 removed the ability to display menu items the user doesn't have access to. However, in some cases it is desirable to show a menu item even though the user doesn't have access to the menu item. For example, if you use an authentication mechanism that tries to acquire authentication when a 403 would be displayed, you still want to display the menu item so that users get a chance to provide credentials to log in.

Comments

+1 for this. Often is useful to show menu items to inform anonyms about members-only sections, features, etc.

Category:feature» bug

I agree, and this is a bug.

I don't know that it's a bug, but it's a missing feature that should be available. I have this issue right now.

I needed this feature. Here's a small module I wrote that allows me to accomplish this. It's somewhat of a hack, but Drupal's design takes the blame. I'm using Drupal 6.x so it's only been tested for Drupal 6.

<?php
/**
* Implementation of hook_form_alter()
**/
function menu_visibility_form_alter(&$form, &$form_state, $form_id) {
  if (
$form_id == 'menu_edit_item') {
   
$form['menu']['always_show'] = array(
     
'#title' => t('Always show'),
     
'#type' => 'checkbox',
     
'#description' => t('If select, this menu item will be shown even if the user does not have permission. (Access will still be denied.)'),
     
'#default_value' => $form['menu']['options']['#value']['always_show'],
    );
   
array_unshift($form['#submit'], 'menu_visibility_menu_edit_form_submit');
  }
}
function
menu_visibility_menu_edit_form_submit($form, &$form_state) {
 
$menu =& $form_state['values']['menu'];
  if (
$menu['always_show']) {
   
$menu['options']['always_show'] = 1;
   
$menu['options']['alter'] = 1;
  }
  else {
   
$menu['options']['always_show'] = 0;
   
$menu['options']['alter'] = 0;
  }
}
/**
* Implementation of hook_translated_menu_link_alter().
*/
function menu_visibility_translated_menu_link_alter(&$item, $map) {
  if (
$item['options']['always_show'] == TRUE) {
   
$item['access'] = TRUE;
  }
}
?>

+1 for the option to turn off this "feature" in D6... we need to let users see that additional content is available. If they can't see the buttons, they don't know it's there. The big problem with this new behavior is that, good or bad, it is unexpected and as such generates a lot of frustration.

I used #4's solution and I can only get block titles but still not the menu items. I have been disabling any and all other modules that have anything to do with taxonomy access and menu access with no luck.

Hi freighthouse, can you determine whether menu_visibility_translated_menu_link_alter is fired?

ummm, would you mind guiding me on that?

@venkatd: For me, yes menu_visibility_translated_menu_link_alter() is fired on each display of the menu for anonymous user. The menu entry is included, but the text of the menu entry is '', so your posted code *almost* works for me, but doesn't quite.

A couple of alternative workarounds for D6 are -

1. Path Access module which provides a means of restricting access without affecting menu visibility (according to the project page).
2. Creating absolute URLs as menu entries. ie, instead of node/123, set the menu entry to http://example.com/node/123. One customer reported that Drupal automatically "corrected" this (haven't tested/reproduced myself); if so then this may be circumventable by assigning meaningless parameters to the absolute URL (http://example.com/node/123?abc=def).

#4's module code worked like a charm on my 6.x install. I added the additional check to put a different css class on the links for anon users:

function menu_visibility_translated_menu_link_alter(&$item, $map) {
     if ($item['options']['always_show'] == TRUE) {
         $item['access'] = TRUE;
         if (user_is_anonymous()){
              $item['localized_options']['attributes']['class'] .= 'anonymouscssclass';
         }
     }
}

Version:7.x-dev» 8.x-dev
Category:bug» feature

This is very much not a bug.

It may not be a bug. But it is a very needed feature. +1 for this.

for the statistics: i am currently building a site, where I would need that feature.

to make the suggestion from #4 in D7 i had to modify minor stuff (this solution is based on the stuff by mthomas in #13)

<?php
//largely based on http://drupal.org/node/300607#comment-2805992
/**
* Implementation of hook_form_alter()
**/
function always_visible_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'menu_edit_item') {
    $form['always_visible'] = array(
      '#title' => t('Always show this menu item.'),
      '#description' => t('Disables the check if the user has access to this path.'),
      '#type' => 'checkbox',
      '#weight' => '0',
      '#default_value' => isset($form['options']['#value']['always_visible'])?$form['options']['#value']['always_visible']:FALSE,
    );
  array_unshift($form['#submit'], 'always_visible_menu_edit_form_submit');
  }
}
function always_visible_menu_edit_form_submit($form, &$form_state) {
  $menu =& $form_state['values'];
  if ($menu['always_visible']) {
    $menu['options']['always_visible'] = 1;
    $menu['options']['alter'] = 1;
  }
  else {
    $menu['options']['always_visible'] = 0;
    $menu['options']['alter'] = 0;
  }
}
/**
* Implementation of hook_translated_menu_link_alter().
*/
function always_visible_translated_menu_link_alter(&$item, $map) {
  if ( isset($item['options']['always_visible']) && $item['options']['always_visible'] == TRUE) {
    $item['access'] = TRUE;
    $item['title'] = $item['link_title'];
  }
}

There is a D6 module that does this here: http://drupal.org/sandbox/mthomas/1119418. D7 patch is in its issue queue.

Priority:Normal» Major

+1 for this.

Just used #15 on D7 and it worked like a charm. Thanks valderama. I agree this should be addressed. Bug or not a bug, it is unexpected

Version:6.x-dev» 8.x-dev
Priority:Normal» Major

code from #15 works on D7 cut and paste.
Thanks you.