Gaining control of menus in Drupal - Part 2
In Gaining control of menus in Drupal - Part 1we looked at the default Drupal output for a menu block and the output we were trying to create. We also create two new files in our theme, block.tpl.php and block-menu-primary-links.tpl.php.
We are now going to look at the template.php file and three functions that will allow us to gain access to the unordered list, list item and even the anchor tags that make-up the menu.
We will start by creating a new php file named, you guessed it, template.php.
Next, we need to head over to api.drupal.org and grab the default code for these functions
First the default code of theme_menu_tree:
function theme_menu_tree($tree) {
return '<ul class="menu">'. $tree .'</ul>';
}
What this does is creates an unordered list for each menu item as well as for any submenu items. I have no need to have a parent level and child level menu item to have the same class so I am going to remove the <ul> tag. I will need to add it back later and will do so in two locations.
So that leaves me with the following code:
function theme_menu_tree($tree) {
return $tree ;
}
Now, those of you that have any experience with the menu system are panicking right now, trust me, it all works out in part three.
Now that we have removed the <ul> tags from all the menis and submenus we need to put them back. Here we will adderess the submenus. Here is the code before:
function theme_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
$class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
if (!empty($extra_class)) {
$class .= ' '. $extra_class;
}
if ($in_active_trail) {
$class .= ' active-trail';
}
return '<li class="'. $class .'">'. $link . $menu ."</li>\n";
}
And here is the code after:
function pennzoil_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
$class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
if (!empty($extra_class)) {
$class .= ' '. $extra_class;
}
if ($in_active_trail) {
$class .= ' active-trail';
}
$sub_menu = (!empty($menu) ? '<ul class="sub-menu">'. $menu .'</ul>' : $menu);
return '<li class="'. $class . '">'. $link .$sub_menu."</li>";
}
As you can see, you can now add whatever class you would like to your submenus. In further tutorials I will talk about further controlling the submenus.
Here comes the real fun and I couldn't do it without my good friend, print_r(). You see, I don't use the theme function too often. I prefer to look at the array and all it's nerdy goodness. The results of using print_r() allowed me to get down to the <a> tag and add the classes that I needed to make my project successful.
Once again, the code before:
function theme_menu_item_link($link) {
if (empty($link['localized_options'])) {
$link['localized_options'] = array();
}
return l($link['title'], $link['href'], $link['localized_options']);
}
and the code after:
function pennzoil_menu_item_link($link) {
if (empty($link['localized_options'])) {
$link['localized_options'] = array();
}
if($link['menu_name'] == 'primary-links'){
if($link['has_children'] || $link['expanded']){
$link['localized_options']['attributes']['class'] = 'main-link';
}
}
return l($link['title'], $link['href'], $link['localized_options']);
}
What I have done here is make sure that these new rules only apply to the Primary Links menu. To meet the requirements I had to add the 'main-link' class to all parent items and top-level items. I hooked into the has_children and expanded items in the $link array.
So there it is. I will tie it all together in Gaining control of menus in Drupal - Part 3

Post new comment