0

I have implemented hook_menu_link_alter so that a menu link is altered for some authenticated users, but not for all. My implementation of hook_menu_link_alter changes properties of the link (HTML attributes), not the destination of the link. The thing that I'm changing is adding an HTML class and other attributes for some users, and not for others. A 3rd party JavaScript that is also loaded reacts differently depending on the attributes.

In Drupal 6 I must clear the cache so that the menu links are rebuild and so that the changes that I have in the hook are applied.

However, that also means that the modified link in stored in the cache. So if another user then logs on who doesn't need the change, then this user also sees the change because it was cached?

I know that a solution could be to have 2 menu's and use PHP code to decide which one is shown to which user, but this is not what I want. I'm building this in a generic module that is available from drupal.org, so I don't was to go duplicating menu's in other people's websites. Another solution could be to rebuild the menu cache after every logon, but I fear that this is quite resource intensive.

Does anybody have advice on how this can be handled?

  • If you are only adding class or changing html of the menu, then you should override theme of the menu rather then implement hook_menu_link_alter. – Jayendra Kainthola Nov 19 '13 at 9:18
  • This is indeed all that I'm doing, but the functionality is part of a custom module. So I want to offer everthing at once via the custom module. Shouldn't an override of the theme of the menu be done from inside a theme? – LVA Nov 19 '13 at 13:56
  • You can also override the menu from your custom module. I have to look into this for proper method, so I will let you know later. – Jayendra Kainthola Nov 19 '13 at 17:02
0

Your idea to rebuild the menu cache on each login would certainly be resource intensive, but it would moreso just not work either as the cache is system wide and isn't somehow custom cached across page loads of a user, so, once someone logged in, it would be rebuilt and then accessible to both that as well as any other currently logged in user. Then, when the next user logged in, it would be rebuilt for all to use by everyone logged in, etc etc etc.

But, you could rather easily as you intimated do this with php inside a new page callback, eg, something along the lines of...

if ( /* users we are looking for is TRUE */ ) {
  // use our new callback
} else {
  // call original callback
}

By doing it inside the callback, you wouldn't be duplicating menu paths, eg, not having module/callback1 and module/callback2 but rather module/callback in itself would do things differently based upon your new logic...much like how going to user as an anonymous user presents a login page, but going to it once logged in presents your profile.

ADDITION:

Given additional commentary, you most probably could overload/overuse the capabilities of hook_translated_menu_link_alter() to accomplish this, eg, something like:

function YOURMODULE_menu_link_alter(&$item, $menu) {

  if ( /* whatever is true for your $item */ ) {
    $item['options']['alter']=TRUE; // Flag this link as needing an alter at display/run time.
  }

}

and then

function YOURMODULE_translated_menu_link_alter(&$item) {

  if ( /* whatever is true for your $item */ ) {

    // do whatever you want to do to it, eg...

    if ( /* this is a special user */ ) {
      $item['localized_options']['attributes']['class']='foo';
    }

  }

}
  • You are right about the periodical cache reset, it wouldn't work for me. I'm not looking for a solution to change the destination of a link, but to how the link is rendered. I have updated my question to better reflect this. – LVA Nov 17 '13 at 19:51
  • ah...you might be able to use translation to your advantage here. see additions in answer. – Jimajamma Nov 19 '13 at 2:25

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.