I was having the worst time with menu_set_location(), completely unable to get it to work in _nodeapi, despite several examples throughout Drupal’s core code of it working during hook_view(). All I wanted to do was hang it off an existing menu item, but it took me an hour to come up with a formula. Almost everything I tried was actually more code than what I eventually came up with.
First, the site I’m working on for this uses a little technique where much of the structure of the site is in the Primary Links block (i.e, with links across the top) and many of those links have children items. But instead of using the secondary links bar, I have them displaying in a block.
<?php
function sws_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks['secondary']['info'] = t('Secondary Menu Block');
return $blocks;
case 'view':
switch ($delta) {
case 'secondary':
return sws_secondary_menu_block();
}
}
}
function sws_secondary_menu_block() {
if ($content = menu_secondary_links()) {
// Get the active menu trail and grab the first one after the Primary Links menu
$trail = _menu_get_active_trail_in_submenu(variable_get('menu_primary_menu', 0));
$pid = $trail[1];
$menu = menu_get_menu();
$block['subject'] = $menu['visible'][$pid]['title'];
$block['content'] = theme('menu_tree', $pid);
return $block;
}
}
?>Second, I have many nodes that might be underneath one of these items, most often through a view. These are, effectively, galleries of one form or another. I didn’t really want to hard code things too much, so this is what I came up with.
<?php
function sws_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($op == 'view' && $page) {
switch ($node->type) {
case 'disknode':
$path = 'community/downloads';
break;
case 'event':
$path = 'event';
break;
case 'product':
$path = 'store';
break;
}
if ($path) {
global $_menu;
// Our current menu item is node/NID/view -- we want to
// grab node/NID (the parent item) and reparent it to
// the menu item for the $path we set earlier.
// If we don't do this, we can lose our tabs.
$mid = $_menu['items'][menu_get_active_item()]['pid'];
$pid = $_menu['path index'][$path];
$_menu['items'][$mid]['pid'] = $pid;
menu_set_active_item($_GET['q']);
drupal_set_breadcrumb(menu_get_active_breadcrumb());
}
}
}
?>I’m not happy that it directly modifies $_menu, but otherwise I think it’s relatively elegant.


primary_links.module
http://cvs.drupal.org/viewcvs/drupal/contributions/modules/primary_links... used to do exactly what you try above. It is old and abandoned (since the functionality moved into core) but might be worth examining, since esp. the splitted menus (primary across top, secondary in a block) is provided by this module.
Bèr
I had to do something
I had to do something similar on a site I'm working on now. My solution was
1. Build the "submenu" block with this code,
$trail = _menu_get_active_trail_in_submenu(variable_get('menu_primary_menu', 0));
$mid = $trail[1];
if (is_null($pid)){
$block = false;
} else {
$item = menu_get_item($pid);
$block['subject'] = t($item['title']);
$block['content'] = theme("menu_tree",$mid);
}
2. Use the normal "admin/menu" conventions to build the page hierarchy-- then Disable the menu items that I don't want displayed in the submenu block.
This is maybe not scalable, since you have to have a menu item for each hidden subpage.
How to pass menu class = "active" ?
Thanks a lot, Earl. I was going crazy because I couldn't get menu_set_location to do anything, and this code got me very much in the right direction. :D
The one thing it's not doing is passing a class="active" to the menu item in question, which is messing up the theming slightly. Any ideas on how I might do that?
well, can we fix thi
any idea how to make menu_set_location() work more intuitive, or at all?
Glad I saw this post
I was just dealing with the same issue and this post saved me. Your approach is not as flexible as menu_set_location(), because with the latter you can add several "made up" menu items in a row. But because I can't afford to lose the tabs, I'm going with your code.
In my case, the parent menu item is a URL alias, so I use this:
<?php// [snip]
$pid = $_menu['path index'][drupal_get_normal_path($path)];
// [snip]
?>
Thanks so much.
Thanks
Good job! I had the same problem and your solution is perfect!
Post new comment