Add unique class to menu items
Last modified: January 24, 2009 - 09:39
There are many times that I prefer to css my menus using individual classes. I am very happy with the results I get with this snippet in Drupal 6:
<?php
function phptemplate_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';
}
if (!empty($link)) {
// remove all HTML tags and make everything lowercase
$css_id = strtolower(strip_tags($link));
// remove colons and anything past colons
if (strpos($css_id, ':')) $css_id = substr ($css_id, 0, strpos($css_id, ':'));
// Preserve alphanumerics, everything else goes away
$pattern = '/[^a-z]+/ ';
$css_id = preg_replace($pattern, '', $css_id);
$class .= ' '. $css_id;
}
return '<li class="'. $class .'">'. $link . $menu ."</li>\n";
}
?>Which provides me with great themable output in the form of:
<li class="leaf myaccount"><a href="/user/1">My account</a></li>
<li class="leaf nodelocations"><a href="/map/node">Node locations</a></li>
Remove after colon? Unique ID? Performance?
Hello,
Why do you
<?php// remove colons and anything past colons
if (strpos($css_id, ':')) $css_id = substr ($css_id, 0, strpos($css_id, ':'));
?>
Does that mean that, if I create a menu item which label is, say, "News: all news", the css_id will only be news?
I have two another remarks:
Don't you think this technique is a performance leak, when many menu items are displayed?
This technique doesn't assure the CSS id will be unique, as many menu items can have identical label.
By the way, thank you for this snippet I will use until I find better. ;)
David
Getting it more usable would be GREAT!!
I have had a tough time finding something that works in Drupal 6 and as a themer, I rely on this awesome community to help with the php. Figured i'd get the ball rolling. I am hoping that some of the master coders in the community will "enhance" it. I would really like if the menu css was the $mid, but I have been unsuccessful in creating that function in the last 24 hours or so.
(repeat class names) By using classes, I have been using the ID or Class of the container to achieve specific theming for specific menu items.
(individual menu's only) I believe there is a solution here http://www.jakob-persson.com/node/535, and/or here http://programmingbulls.com/drupal-how-theme-menu to make them menu specific, haven't figured it out yet.
Another option I have been looking at is:
<?phpfunction YourThemeName_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';
}
$id = preg_replace("/[^a-zA-Z0-9]/", "", strip_tags($link));
return '<li id="'.$id.'" class="'. $class .'">'. $link . $menu ."</li>\n";
}
?>
from http://drupal.org/node/67457#comment-864218
ideas, help, and improvements are very welcomed!!!
Add IDs only for one ore more special menu?
If I do so as mentioned, all the links in all the menues all over my page are rendered by this function. but i only need the id's in special cases. Is there a chance to do a more specific override? Like:
function themename_menu__primary_links_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {...
}
And BTW whats up with that $extra_class?
Issue created
I created issue 475734 to discuss this.
Awesome!
This is exactly what I was looking for. Thanks!