2

I am developing an application based on Drupal 7 and web services. Some application pages have a menu which should be customized (menu items should be removed) based on the response from the web service, but am not sure on how should implement it.

In general the logic is the following: I will get a parameter from the request and call the web service with PHP (I know how to do this). Then, based on the response, I should show or hide some menu items.

The problem is that the menu should be customized in every request, so hook_menu_alter does not help me, because it is only called once when the menu is created. Is there another hook that I should be looking into, or any other method I should be using?

5
  • Is there any logic for the request? May you do an example? Commented Dec 20, 2012 at 12:08
  • Hi Syd, I added some extra info Commented Dec 20, 2012 at 12:21
  • I'm not sure but... maybe you can create a content type with links a related it with a view instead of menu items. Or you you can try Menu Block, but It's still not quite clear, can you provide a detailed example? Commented Dec 20, 2012 at 13:53
  • Thanks for your suggestion, I'll try to replace the menu with a custom view. Sorry if I didn't give enough details, but I'm not that experienced in Drupal Commented Dec 20, 2012 at 14:30
  • If you give us a detailed example on what's your menu items and what kind of link you want to show depending on the content. Commented Dec 20, 2012 at 14:53

3 Answers 3

4

use theme_menu_link() to modify your menu links on the fly:

  • style="display:none"
  • class="invisible"

e.g.

function mytheme_menu_link(array $variables)
{
   if ($variables['element']['#href']=='temp-menu-link') {
       $variables['element']['#attributes']['class'][] = 'invisible';
   }
   return theme_menu_link($variables);
}

Security note: It'll still be possible to access the URL, thus a "state check" must be implemented on the receiving end if temporarily invisible also means 'not permitted to call'.

3
  • Thanks, I too believe that this would be the best way to go, but I ended up reimplementing the menu as a custom PHP page. So I'm accepting this as the correct answer even though I have not tried it. Commented Dec 21, 2012 at 10:21
  • Could I just unset($variables['element'])? I.e. is this array completely mutable?
    – Steve Clay
    Commented Apr 29, 2014 at 18:03
  • how to do same thing for drupal 9, hook_menu_link is not available for drupal 9
    – user106854
    Commented Jan 9 at 9:44
1

You can use hook_menu_alter if it's solve your problem. You can call this hook as many as you like with module_invoke_all('menu'). Note that you need to clear the menu cache after altering a menu.

1
  • Could you add an example? I'm having trouble understanding where to put which part of the code. Where should I be calling module_invoke_all('menu'), for example?
    – Shawn
    Commented Jan 11, 2013 at 21:09
1

I was able to accomplish this by loading the menu with the link in question. I then acted upon this menu item using its link path. I set the links hidden attribute to 1 to hide it. I then saved the menu link. Then I cleared the menu cache. For the use case for this question, you would just do this when the web service call happens that is requesting to hide the menu. Here is what the code looks like.

$links = menu_load_links('secondary-navigation');
foreach($links as $item) {
    if ($item['link_path'] == 'blog') {
        $item['hidden'] = 1;
        menu_link_save($item);
        menu_cache_clear('secondary-navigation');
        break;
    }
}

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.