Hi,

I'm currently trying to theme Drupal, and am implementing a main site nav as a menu. The site nav uses CSS tabs that require the LI of an active tab to hold the 'class="active"' portion of code rather than the A tag as is usual with Drupal.

Is there anyway to achieve this? I've search drupal.org and there doesn't seem to be any fixes or mods that will do quite what I want. I've also ducked around the source code, but I can't find where the relevant piece of code despite doing a search on the drupal folder.

Any help would be overwhelmingly appreciated :-)

Also, would it make more sense in some ways to have the LI carry the class="active" declaration as standard, as then a CSS rule can easily cascade down the hierarchy:

i.e.

LI.active A { styles..... }

as well as allowing

LI.active

Comments

monkeybeach’s picture

:)

monkeybeach’s picture

is there really no way to alter this?

monkeybeach’s picture

After much reading and messing around with templates and php, I've found a way of achieving this for the home page.

This requires the patch to allow an active class to be added to the home link on the home page (see here: http://drupal.org/node/45098)

You can then use str_replace in the home page template to alter the location of the class="active" string.

<?php 
//Modify the Header to place 'active' class into the LI not the A :)
print str_replace ('<li class="leaf"><a href="/drupal/" title="" class="active">Home</a></li>', '<li class="active"><a href="/drupal/" title="">Home</a></li>', $header); 
?>

I'm not sure I like it messing with the href in the link though, and because it does this its not going to work with the templates which power more than one page.

Possibly something using regular expressions would fix this for other templates.

monkeybeach’s picture

Ok, I figured it out :)

You need to use this code on page.tpl.php in your theme instead of the standard call to display the $header:

<?php
// Remove all 'class="leaf"' strings as I'm not using them to style the menu

$pattern = '/class=\"leaf\"/';
$replacement = '';
$defoiliatedHeader = preg_replace($pattern, $replacement, $header);

// Move the 'class="active"' string from the A tag to the LI tag where it can be used to style both the active LI and A tags

$pattern = '/<li ><a href=\"(.*?)\" class=\"active\">(.*?)<\/a><\/li>/';
$replacement = '<li class="active"><a href="$1">$2</a></li>';
echo $fixedHeader = preg_replace($pattern, $replacement, $defoiliatedHeader);
?>

I still think that making a change to Drupal to permanently shift the 'class="active"' to the LI tag is more useful for CSS coders and a minimal change. I'd imagine it would require many themes to be updated however.

lammmy’s picture

I found a somewhat fix in teh menu.inc file
I changed the function theme_menu_item() from

function theme_menu_item($mid, $children = '', $leaf = TRUE) {
  return "\t\t\t\t\t\t<li>". menu_item_link($mid) . $children ."</li>\n";
}

to:

function theme_menu_item($mid, $children = '', $leaf = TRUE) {
  $output = "\t\t\t\t\t\t<li";
  if(menu_in_active_trail($mid)){
    $output .= " class=\"active\"";
  }
  $output .= ">" . menu_item_link($mid) . $children ."</li>\n";
  return $output;
}

Seems like quite the hunt just to find out how to change one little class...I don't think the core programmers have ever heard of the MVC method of development, would have really helped to not have output/logic/database code all mashed together into one ball of fun!

Hopefully that helps out a bit.

lreid’s picture

I made great use of this trick in 4.7--but I can't figure out how to implement it in 5.1. Has anyone done it?

aether’s picture

I was able to accomplish this in 5.1 with the following code:

// Add 'active' class to <li>
function theme_menu_item($mid, $children = '', $leaf = TRUE) {
  if (menu_get_active_nontask_item() == $mid) {
    $class_active = 'active';
  }
  return '<li class="'. ($leaf ? 'leaf ' . $class_active : ($children ? 'expanded ' . $class_active : 'collapsed')) .'">'. menu_item_link($mid) . $children ."</li>\n";
}

Place this in template.php. Replace "theme" in the function name with the name of your theme.

Jeff Tomlinson

lreid’s picture

It works!

twiik’s picture

for some reason.

But if anyone else is having troubles with the above mehtod and wants to do this I did it with jquery instead:

$(document).ready(function() { 		
	//Adds an active class to the parent li of the active a
	$("ul.menu a.active").parent("li").addClass("active");	
});

Øyvind Strømsvik
oyvind@nymedia.no
Ny Media AS - www.nymedia.no

Øyvind Strømsvik
Tech lead | Frontkom AS
https://frontkom.com/

langweer’s picture

Remember to change "theme_menu_item" into "yourtheme_menu_item".