How do I dynamically set the active menu item?
Solution 1:
For similar purpose, I used menu_set_item()
. You should leave the $path
argument NULL
and use the menu item for the internal path of 'galleries/lastgallery'
as $router_item
.
function custom_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if ($op == 'view' && $node->nid == 31) {
$path = drupal_get_normal_path('galleries/lastgallery');
if($path && $menu_item = menu_get_item($path)) {
menu_set_item(NULL, $menu_item);
}
}
}
Solution 2:
As tmsimont pointed out, using menu_set_item()
has side-effects...
A quick look at menu_set_item() and menu_get_item() shows us that they trigger hooks and database calls (). Not perfect.
If you're using Drupal 7.9+, there's a new function called menu_tree_set_path()
that will do the trick:
menu_tree_set_path('user-menu', 'shopping-cart');
The first argument is the menu name followed by the path you want to select.
NOTE: This does not apply the .active
class but applies .active-trail
instead so you'll have to update your CSS to accommodate both!
Solution 3:
I know I'm a bit late in the game here and this already has an answer but I thought I'd post this in case it helps someone
With reference to the problem of menu_set_item(NULL, $menu_item) killing local tasks - it's not limited to this.
I found that when using the discuss module it didn't load the block. I think the issue is that by doing something like:
$path = drupal_get_normal_path('galleries/lastgallery');
$menu_item = menu_get_item($path);
menu_set_item(NULL, $menu_item);
You effectively tell drupal you're on a different page/item.
The solution that worked for me was this:
$menu_item = menu_get_item();
$menu_item['href'] = 'galleries/lastgallery';
menu_set_item(NULL, $menu_item);
This seems to just play with the href and leave rest alone so local tasks still work and so did disqus.