Introducing the Menu Attributes module

Over the Christmas break I decided that I’d had enough of hard coding theme functions to add attributes to specific menu items in Drupal, so I finally took the time to write a module that would do the heavy lifting. The outcome is the Menu Attributes module.

All the module does is give you the ability to add attributes to the menu item <a> elements, but this has been something I've wanted in Drupal for a long time now.

The main reason I wrote the module was to add the rel="nofollow" attribute to certain menu items (learn why you should be using nofollow to direct PageRank to high value pages), but it made sense to allow users to set other valid attributes as well. So far I have included the Id, Name, Target, Rel, Class, Style, and Accesskey attributes which can be added to any menu item. If you think other attributes would be useful, let me know I’m happy to consider including them.

In the next couple of weeks or so I’ll be releasing an update to include an admin page so that you can choose which attributes are available on the menu form so as not to overcrowd the form with items that you’ll never use.

It’s worth noting that the actual attributes are stored in the menu_links table in the options field of the menu item itself so no new databases are needed and no additional processing done when building the menu. The one drawback of this is that there is no way to mass reset the attributes you’ve set using the module, because it is stored alongside other attributes that are set by other modules.

If you’ve got any other uses or feedback for the module, I’d love to hear them in the comments.


Thanks for a great module!

I would love to see automatic creation of id's and classnames. Perhapse using patterns like pathauto:

Glad you like it.

The problem with doing something like that is that menu items are not always linked to nodes, they could be linked to external sites, files, or anything else, so what would we do in that situation? What you want to do is probably best left to a specific module that processes the menu before it is displayed (rather than before it is saved like this one does) or build it into your theme.

was getting an error
notice: Undefined index: id in /var/www/.../modules/menu_attributes/menu_attributes.module on line 68.

change line 64 to
if (variable_get('menu_attributes_id_enable', 1) && isset($item['options']['attributes']['id'])) {

and it fixed it.

Just letting you know.

thanks man...

I added a bit to your module, an onClick for the pageTracker so that my analytics can track off-site links.


Wouldn't it be better to target the menu item li instead of the ?

Or wouldn't it be better to have fields for such?

All styling and jquery related tasks that target the <a> are still feasible, but now you can affect the parent <li> as easily.

Also I think that using Schoonie's idea is feasible for using menu related tokens.


sorry about badly formatting my last post, it's obviously too late for me to be writing this to you.

I meant to ask:

Wouldn't it be better to target the menu item < li > tags instead of the < a > tags. This would make targeting the parent list items feasible, without affecting your ability to target the anchors?

Then I actually checked your module and realized that the code that you're plugging into doesn't get to affect the list-item; it uses the existing theming functionality of the menu system, which only themes each anchor and then drops it into a list item.

Sorry about that.

I wonder if someone could suggest a good way to overload menu items with images.

First I'm using this fantastic module to set a unique id for the menu item (e.g. #menu-item)

I'm using some css along the lines of:
#menu-item {
font-size: 0px; /* hide the link text */
display: block; /* force the size of the anchor */
width: 200px;
height: 25px;

background-image: url('image.jpg'); /* place the image */
#menu-item:hover {
background-image: url('hover.jpg');
#menu-item:active {
background-image: url('active.jpg');

In particular I'm focusing on how to hide the old link text, but keep the text, and have it make the entire background image an active target for a click.
I'd like to do this using just css of course, and not have to resort to using jquery to remove the old text.

The problem is that the fashion of hiding the text isn't working on all version of webkit. Is this font-size=0 what other people are doing?


Holy crap, thank you so much. I've been working on creating a theme from scratch for the first time, and I needed to use images in my primary links. This helps immensely!