Unique Class for Cool Drupal Menu Items

11 Dec in drupal, php, snippet, theme

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.
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 '<li class="'. $class .'">'. $link . $menu ."</li>\n";
}

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

<li class="leaf myaccount"><a href="/user/1">My account</a></li>
<li class="leaf nodelocations"><a href="/map/node">Node locations</a></li>

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 '<li id="'.$id.'" class="'. $class .'">'. $link . $menu ."</li>\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

is this something edited in

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

template.php

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

thanks

This works great!

not compliant with acquia marina theme

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.

disregard that last comment

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

Nothing changes

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,

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.

One summer afternoon, Former

One summer afternoon, Former President Bill Clinton and his wife Hillary were vacationing in their home state of Arkansas. After a long road trip, they stopped at a service station to fill up their car with gas.A blind man, with a seeing eye dog at his side, walks into his local grocery store.

sanejenny

As an agent, we must stick together in every situation of customers. That's not problem if one agent have to serve another agent's customer. pool table

Post new comment