Hi

I have created a menu programmatically where each menu entry is related to a node, say there are three nodes:

title = 'level0'
nid = 555
path alias '555'

title = 'level1'
nid = 556
path alias '555/556'

title = 'level2'
nid = 557
path alias '555/556/557'

First menu entry is given the name: level1 and a path '555'

Second menu entry is given the name: level2 and a path '555/556'

Third menu entry is given the name: level3 and a path '555/556/557'

Now if I force each menu item to be expanded (when I create the menu) the menu block shows all the items and clicking on each displays the correct node.

level1 => node 555
---level2 => node 556
------level3 => node 557

The root menu entry (level1) is given a type of 115, and the others are 118 (plus the expanded flag).

However under normal conditions I only want to force the level1 to be automatically expanded (so it displays level2) and leave level3 (and anything deeper) collapsed, so it looks like this:

level1
---level2

Now clicking on level2 displays node 556 (which is what I want) but the menu doesn't get expanded to display the level3 entry, and it needs to.

I believe the menu is being constructed correctly -- because it's fine when I force every item to be expanded and all the nodes are displayed correctly. So what do I need to do to force the expansion of the level2 menu item when it's selected?

I have spent a long time looking at menu-related issues and tried various things but nothing seems to deal with this directly or provide the necessary hints.

Steve

Comments

SteveTurnbull-1’s picture

any ideas???

SteveTurnbull-1’s picture

??

newdru’s picture

but a question.

can you post a code snippet on how you *programatically* created the menu items?

fwiw, tying the menu system and it's states to viewed nodes is not the easiest thing from my past experience. it's one of the weaknesses of drupal. that said, i would think if you've created the menu items programatically they should behave as they would had you created them manually in the menu system. meaning that i think what you're trying to do should work. as a test, you might want to see if you can achieve what you want *first* by *manually* creating some menu links. if they work in the manual system, you know they should work when created programatically. in fact, it's possible you could trace the menu code to see what it's doing.

also, i believe drupal 6 is supposed to have a much better menu system (i think redesigned from scratch) that offers more of the capabilities missing in prior versions. unfortunately, many folks can't move to d6 due to it's lack of module availability, esp key modules.

SteveTurnbull-1’s picture

First of all it seems my menu problem was the result of inherited code, I'm working on a major installation and there was some legacy code in the template.php of the theme I was using that was already fiddling with menus. I changed themes and voila, it all worked fine.

/**
 * Create an actual menu from a set of entries
 *
 * The first level of menu items should be expanded,
 * then the rest is collapsed
 */

function _yourmodule_make_real_menu($menu) {
	$item = array(
		'pid' => 0,
		'type' => 115,
		'title' => $menu->name
		) ;
	menu_save_item($item) ;
	if ($menu->entries) _yourmodule_make_real_menu_item($item['mid'], $menu->entries, true) ;

	return $item['mid'] ;
}

function _yourmodule_make_real_menu_item($pid, $entries, $open = false) {
	$weight = 0 ;
	foreach ($entries as $entry) {
		$item = array(
			'pid' => $pid,
			'path' => $entry->path,
			'title' => $entry->name,
			'weight' => $weight++,
			'type' => 118 | ($open * MENU_EXPANDED)
			) ;
		menu_save_item($item) ;
		if ($entry->entries) _supertax_make_real_menu_item($item['mid'], $entry->entries) ;
	}
}

The $menu parameter in the top routine is tree of a stdClass object with these fields:

name
The name/title of the menu item
path
The URL for this menu item -- what it links to
entries
Array of child nodes of this same type

Things to know: You have to view the menu page and then view the block page in order to get the menu block to appear. This may be possible programmatically but I haven't sorted out the calls. Obviously you still need to go to the blocks page in order to specify where you want this menu block to go.