Unique Class for Cool Drupal Menu Items

I spend the majority of my time around Drupal in the areas of website building and in the theme layer. Anytime I can find things to make my theming life easier in either... I take it.

One of the 'limitations' (using that friendly) is the options for theming. IMPORTANT to note... Drupal 6 ROCKS!! THEMING!!. One of the important 'additions' I try to create when working in the theme layer is to improve my ability to use CSS. Some sites require fancy, creative, and/or custom stuff revolving around menus.
[inline:newlinks.png]

There are times that I prefer to style my menus individually/uniquely. The ability to inject classes into the xhtml. For a start, I have been happy with the results I get with this snippet for Drupal 6:

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 '

  • '. $link . $menu ."
  • \n";
    }

    Which provides me with some good class tags to work with. The themable output in the form looks something like this:

  • My account
  • Node locations

  • [inline:codeoutput.png]

    It was suggested that this solution is basically bulky. Which is probably true... some of the issues include (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, and plan to use is:

    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';
    }
    $id = preg_replace("/[^a-zA-Z0-9]/", "", strip_tags($link));
    return '

  • '. $link . $menu ."
  • \n";
    }

    which I snagged today from http://drupal.org/node/67457#comment-864218

    That's all for now. Feel free to add your ideas, help, and improvements... they are very welcomed here!!!

    Comments

    7

    is this something edited in the page.tpl.php file or the templates.php file or another file somewhere?

    Template.php is your friend. That is where the functions live. It's called a 'theme override', however, I call it cut, paste, alter :)

    This works great!

    Tried to get this working on the acquia marina theme, but to no avail. Classes simply aren't output. I'm not much of a php developer, so wonder if something in that theme specifically is causing problem.

    doh! didn't remember to turn off caching. never mind. works great!

    When I place the snippet in my template.php file, clear the cache, and load the page: nothing changes. I then used the devel module to show me what function was rendering the primary links (what I mainly want to style). It said theme_links() rather than theme_menu_item() was rendering the menu. Could this be an explanation why something didn't happen? Should I override the theme_links() instead? Thanks, Will

    These are great solutions, but you could also try the Menu Attributes module (http://drupal.org/project/menu_attributes). This works well for me, in conjunction with the Fusion theme and the super fish jquery menu.