Adding an "active" class to primary links - Option 2
There are quite a few posts about setting the active trail properly with primary & secondary links. In Drupal 5.x, its actually handled pretty well if you use the following code to print your primary & secondary links in page.tpl.php
<?php
print theme('links', $primary_links);
print theme('links', $secondary_links);
?>This is all good and well, but for us themers, there's a little snag. You cannot use a generic style like a.active to hit the active menu items. By default they've got a bunch of numbers tagged onto the word "active" e.g. menu-1-3-2-active. So, basically, you have to know that menu id number to style it. Throw in 20-30 menu items, and your stylesheet is going to get seriously bloated.
The function that creates the output for the primary and secondary links is in menu.inc and is not a theme function. Hence, no simple theme override in template.php. After trolling the forums and checking out the menutrails module, I hit upon the following technique that seems to work nicely.
Step 1 - override the primary & secondary links function
Yes, you're right, you cannot do a direct theme override, because its not a theme function. But you can redefine the primary and secondary links variables by using _phptemplate_variables, before they get to page.tpl.php.
In template.php add the following code:
<?php
function _phptemplate_variables($hook, $vars = array()) {
switch ($hook) {
case 'page':
// reset primary & secondary to use our own function
$vars['primary_links'] = new_primary_links();
$vars['secondary_links'] = new_secondary_links();
break;
}
return $vars;
}
?>If you already have that function in your template.php file (quite likely), then you most likely have the case 'page' bit too. In this case just add inside that section:
$vars['primary_links'] = new_primary_links();
$vars['secondary_links'] = new_secondary_links();Step 2 - rewrite the menu function
Now we can write our own function to create the menu links. For me, the core function was good enough, except for that "active" class. So all I did was copy and paste the functions for primary and secondary links, and add in a separate "active" class. Here's the code (somewhere in template.php):
<?php
/**
* Returns an array containing the primary links - modified to add in a separate "active" class.
*/
function new_primary_links($start_level = 1, $pid = 0) {
if (!module_exists('menu')) {
return NULL;
}
if (!$pid) {
$pid = variable_get('menu_primary_menu', 0);
}
if (!$pid) {
return NULL;
}
if ($start_level < 1) {
$start_level = 1;
}
if ($start_level > 1) {
$trail = _menu_get_active_trail_in_submenu($pid);
if (!$trail) {
return NULL;
}
else {
$pid = $trail[$start_level - 1];
}
}
$menu = menu_get_menu();
$links = array();
if ($pid && is_array($menu['visible'][$pid]) && isset($menu['visible'][$pid]['children'])) {
$count = 1;
foreach ($menu['visible'][$pid]['children'] as $cid) {
$index = "menu-$start_level-$count-$pid";
if (menu_in_active_trail_in_submenu($cid, $pid)) {
$index .= "-active active"; // **** HERE'S THE CHANGE
}
$links[$index] = menu_item_link($cid, FALSE);
$count++;
}
}
// Special case - provide link to admin/build/menu if primary links is empty.
if (empty($links) && $start_level == 1 && $pid == variable_get('menu_primary_menu', 0) && user_access('administer menu')) {
$links['1-1'] = array(
'title' => t('Edit primary links'),
'href' => 'admin/build/menu'
);
}
return $links;
}
/**
* Returns an array containing the secondary links - calls the new primary links function.
*/
function new_secondary_links() {
$msm = variable_get('menu_secondary_menu', 0);
if ($msm == 0) {
return NULL;
}
if ($msm == variable_get('menu_primary_menu', 0)) {
return new_primary_links(2, $msm);
}
return new_primary_links(1, $msm);
}
?>And that's it. Pretty simple really.

That fixed it!
Dave, thank you so much! Was having a problem modifying the menu for my wife's site and your tip helped! Cheers, Ed
Really close
This looks like a clean implementation of adding an active class, however if I have a menu item pointig to , it doesn't set the attribute correctly.