adding ‘first’ and ‘last’ class to Joomla Menu items : Menu overrides

one often needs to define the first and last element in navigation menu. It is needed when you want to remove the last/first unwanted border or maybe if you want to highlight the first item differently. The effect can be achieved by adding an extra class “first” and “last” to the respective child elements of the menus. It is a much sought after feature and I feel should be made the default feature of joomla menu system.

Joomla has a mod_mainmenu module for creating menus. Joomla allows the users to create overrides to get this special enhancements. We would make an override to joomla’s ‘mod_mainmenu’ module to get out classification finctionality.

The overrides are placed in a folder named “html” inside your template folder. Inside ‘html’ place another folder called ‘mod_mainmenu’ to specify the override. Next, copy the file default.php from modules/mod_mainmenu/tmpl from your joomla filesystem to our folder(mod_mainmenu). I recommend you get your own file it may avoid any version related issues. Your default.php file is now located similar to:

templates/MYTEMPLATE/html/mod_mainmenu/default.php

open the file and navigate to the ‘ul’ component which looks like

if ($node->name() == 'ul') {
	foreach ($node->children() as $child)
	{
		if ($child->attributes('access') > $user->get('aid', 0)) {
			$node->removeChild($child);
		}
	}
}

We will add a few lines of code to this to get the ‘first’ and ‘last’ class in the menu items. Our new block will look like :

if ($node->name() == 'ul') {
	foreach ($node->children() as $child)
	{
		if ($child->attributes('access') > $user->get('aid', 0)) {
			$node->removeChild($child);
		}
	}
        //NEW CODE STARTS HERE
	$children_count = count($node->children());
	$children_index = 0;
	foreach ($node->children() as $child) {
		if ($children_index == 0) {
			$child->addAttribute('class', 'first');
		}
		if ($children_index == $children_count - 1) {
			$child->addAttribute('class', 'last');
		}
		$children_index++;
	}
        //ENDS HERE
}

We are done. Just update the file on your webserver and test it. Now the menu child items must get classified. You can now use these classes to transform the look of its children elements.

Share with others :
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Technorati
  • Twitter
  • Live
  • MySpace
  • StumbleUpon


38 Responses to “adding ‘first’ and ‘last’ class to Joomla Menu items : Menu overrides”

  1. ponger says:

    little, but great modification.
    exactly what I need.
    Thank you!

  2. Mike says:

    Thanks for this post it got me on the right track to what I was trying to do. I needed a unique and predictable class on each and every menu item so I could style each one differently and whilst it needed a bit of adapting this was basically the answer.

  3. philip says:

    Most excellent script. The only way I’ve been able to manage this so far is with CSS3 last-child which at present has limited support. Thanks to your help I now have cross browser joomla last-child alternative

    THANKS!

  4. [...] started poking around and ran into an August 2009 blog entry from Cecil Gupta that addresses the problem nicely.  It shows you how to modify the menu code in [...]

  5. DK says:

    Thank for this short and sweet script.
    Excellent work. Thank You.

  6. Gijs says:

    Hurray!!

  7. PerlaRenee says:

    aw, i love this mod :) thanks

  8. Jonathan says:

    Ive tryied using this script for my joomla 1.5.15 pages and nothing seems to make it work. is this compitible with the latest version? i have a simple 1 level menu in Ul format (not the table format) and the first and last class will not get added… i dont understand this is simple i did exactly like stated. i also tried puttin it in templates/MYTEMPLATE/html/mod_mainmenu/default.php AND templates/MYTEMPLATE/html/mod_mainmenu/tmpl/default.php and no luck i even overrided the orginal one in the modules still nothing…. i need this to work badly

  9. cecil says:

    You need to check if you are even using the joomla native mainmenu module to render the menu. I doubt that because only then editing the files shall have no effect on the frontend. The trick applies till the latest version of joomla and works great.

  10. Jonathan says:

    Yup using mod_mainmenu the base menu included with joomla. i have a 2nd menu type installed in a diffrent position: http://box1.thegiant.ca/~belo/index.php?option=com_content&view=article&id=2&Itemid=2 the menu on the right is the one im trying to add the first last to. i changed the code you have above that starts on line 27 in the file default.php i really dont get why this isnt working. i tryied using a base joomla template and i still dont see the first last

  11. cecil says:

    Just tested the override on Joomla 1.5.17. Works cool for me.

  12. Thank you for the great tip. I tried to migrate a Joomla site to a server running PHP 4.4.9 and noticed this did not work. The class name seemed to be over-ridden by the ‘item1′, ‘item2′, etc, rather than appended to it. Maybe this was the problem that Jonathan experienced. It worked great with PHP 5.2.9.

  13. Bobby says:

    I have found that if you have any submenu items (children) under the first top-level item, the top-level item loses the ‘first’ class.

  14. Alexxandar says:

    Just what I needed, thanks!

  15. Laurie says:

    Thanks! you are a lifesaver!
    :)

    (this should SOOOO be in the core!)

  16. cecil says:

    Thank you for your feedbacks

  17. Duane says:

    @Bobby: I have also noticed that the classes are not added if the menu item has any children, that is because the ‘parent’ class overwrites all classes instead of being appended.

    To fix it, look for the following block of code in templates/MYTEMPLATE/html/mod_mainmenu/default.php, it should be directly after the code you’ve added above:

    if (($node->name() == ‘li’) && isset($node->ul)) {
    $node->addAttribute(‘class’, ‘parent’);
    }

    and replace it with:

    if (($node->name() == ‘li’) && isset($node->ul)) {
    if ($node->attributes(‘class’)) {
    $node->addAttribute(‘class’, $node->attributes(‘class’).’ parent’);
    } else {
    $node->addAttribute(‘class’, ‘parent’);
    }
    }

  18. Great! Probably the best post about some joomla module override. Worked at the first try. Simple, but perfect.

  19. Pawel says:

    Great script!
    Thank you!

    I’ve got the question:
    How to add both “first” and “last” class to one element?

    I created new clas “first_and_last” and added code:
    —————————
    if ($children_count==1) {
    $child->addAttribute(‘class’, ‘first_and_last’);
    }
    —————————
    after
    —————————
    if ($children_index == $children_count – 1) {
    $child->addAttribute(‘class’, ‘last’);
    }
    —————————

    but its not the best solution

  20. cecil says:

    you code looks logical to me, doesnt it work right ?

  21. Pawel says:

    @cecil

    Yes, it works.
    I wonder if is better way e.g.
    add two classes ()
    but I don’t know how to do it.

  22. cecil says:

    Yes, sure there is, just make it “first last”.

  23. ~’; I am really thankful to this topic because it really gives great information -,,

  24. google_boy says:

    thanks for the solutions..

    I am stuck in joomla 1.6 module. there is only mod_menu.. I succedded in adding class but bit wrong..

    heres my code

    $total = count($list);
    $total_index = 0;
    echo $total;

    foreach($list as $ite){
    //print_r($ite);
    if($total_index == 0){
    $class .= “first”;
    }
    if($total_index == $total – 1){
    $class .= “last”;
    }

    }
    $total_index++;

  25. Tom Kilbourn says:

    Will you be able to provide a version of your code to work with Joomla 1.6? The mod_menu module suffers the same lack of First and Last classes when creating menus. Thankyou.

  26. aflex says:

    Works perfectly. Yo can see effects on my website;]
    Thx!

  27. J-P says:

    Aaah, just what I was looking for, thank you. This just saved many many hours today.

  28. Shane says:

    Just what i needed. Thank you.

  29. SPeed_FANat1c says:

    Hi, this is awesome. It is hard for a begginer in joomla to figure out the component code myself to make changes (thanks joomla for you “simplicity”..). This is what I needed, thank you.

  30. Mario says:

    Hello, I just stop by to thank you for this. I need this for 2 days now, and thanks god that I found you!

  31. Fabio Berger says:

    I know this is an old post, but today, July 2011, it helped me A LOT!!!! I was breaking my head with lots of css designs, and this post really helped me. THANK YOU!

  32. Robert Went says:

    This is great!
    It would also be good to know how to add a class to the anchor tag.
    I need to move the ‘parent’ class from the li to the a but can’t see to find a way to do it……

  33. cecil says:

    That would make less sense in terms of styling. You can access the anchor tag through css using “li.parent a” rule and style it anything. I cant think of a situation where the “parent” class essentially has to be put to the anchor element.

  34. Robert Went says:

    I was trying to use this css menu http://www.lwis.net/free-css-drop-down-menu/
    For some reason they have the parent class attached to the anchor.
    In the end the template I was using for the menu didn’t fit with the site anyway so I just used one of the others and now it’s looking good.
    Thanks for the first/last tip, you just saved me hours!

  35. Awesome …. I was eagerly looking for it… Thanks to publisher

  36. Michael Kadrie says:

    I don’t know if someone can readily answer this, but how would you apply the “first” and “last” to just the top levels and not the children?

    First Item

    First Child
    Second Child

    Last Item

  37. Michael Kadrie says:

    Sorry, it posted it as HTML.

    [ul]
    [li class="first"]First Item
    [ul]
    [li]First Child[/li]
    [li]Second Child[/li]
    [/ul]
    [/li]
    [li class="last"]Last Item[/li]
    [/ul]

  38. santosh says:

    great code

    Thanks a lot

Leave a Reply