If you run a Drupal site with various sections based on node types this snippet can be useful to enhance the navigational experience of your visitors.
Drupals theme_menu_tree() function offers the classes you need to highlight active menu items. But this does not work for nodes that have no menu item assigned.
To give a real world example. I run a site with a video section. In my primary links menu I have a menu item called Videos. There are several sub menu items such as most viewed, recently added, etc. When a visitor clicks on Videos the menu is expanded. Then the visitor clicks on recently added, the menu is still expanded, that is what I want. Now when the visitor actually clicks on one if the videos listed under Videos -> recently added he or she is directed to the node the video is contained in. This node has no menu item assigned and so the menu is not expanded any more. This is not what I want.
The solution for this problem is quite easy thanks to Drupals flexibility. Here we go:
Step 1
In your template.php file add the following function:<?php// override theme_menu_item functionfunction phptemplate_menu_item($mid, $children = '', $leaf = TRUE) {
return _phptemplate_callback('menu_item',
array('mid' => $mid, 'children' => $children, 'leaf' => $leaf));
}?>Step 2
Create a new file in your template directory called menu_item.tpl.php. This file contains the following lines of code:<?php
$link = menu_item_link($mid);
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
}
if ($node->type == 'video' && $mid == 158) {
$tree = menu_tree(158);
$children = "\n".'<ul class="menu">'. $tree ."\n".'</ul>';
// add active class to link
$link = str_replace('<a ', '<a class="active" ', $link);
}
$output = '<li class="'. ($leaf ? 'leaf' : ($children ? 'expanded' : 'collapsed')) .'">'.
$link . $children ."</li>\n";
print $output;?>How does this work?
Step 1 tells Drupal to override the theme_menu_item() function.In Step 2 first we load the current menu item link and assign it to the variable $link. To get information on the node type we retrieve the current node object by passing the node id (arg(1)) to the node_load() function. Then we check whether this node is of the type video. If this returns true and the current menu id equals the id of the menu item called Videos (in my case 158) we assign the $children variable the sub menu tree of the current menu item add the active class to our link and print out the modified list item.
Now when a visitor watches a video the navigation menu is expanded and gives a clear indication that the visitor is in the video section of the web site.
No comments:
Post a Comment