One of the great new features introduced in the latest WordPress (3.0) update is the menu feature. Now I’m not going to go an about how great all of this is and how life will never be the same because that’s getting a little tired now, but I did find myself needing to style the last items in both menu’s I was using to remove a pipe character from the footer menu and a background image from the main Nav. So for anyone interested heres how to add a class name to the the last LI in an UL generated by wp_nav_menu().
/* Add last_item class to last li in wp_nav_menu lists*/
function add_last_item_class($strHTML) {
$intPos = strripos($strHTML,'menu-item');
printf("%s last_item %s",
substr($strHTML,0,$intPos),
substr($strHTML,$intPos,strlen($strHTML))
);
}
add_filter('wp_nav_menu','add_last_item_class');
You can add this example anywhere in your functions.php file. It’s worth mentioning that this example relies on you using the default list item classes provided by wp_nav_menu, but you can easily update this by adding the li class you are using:
$intPos = strripos($strHTML,'my-li-class-name');
There are tonnes of ways to do this but this is clean and simple string manipulation, so the overheads are quite low compared with the PREG/EREG approach.




16 Comments
This is great! How can you get it to apply to nested lists (2-3 levels deep)? I would like to use this to effectively replace the :last-child pseudo-class. Currently it only works on the VERY last in wp_nav_menu, not the last within each .
Hi Steve, thanks. You might be better off trying to use preg_match if you want to add a class recursively, the strpos approach is simpler but not as flexible. Alternatively you could use jQuery’s pseudo-class selector along side your CSS pseudo which should make IE6 play nicely :), something along the lines of:
$(‘ul li:last-child’).addClass(‘last’);
Steve, few days ago I was dealing with the same problem and have quickly solved that with this code http://www.bouk.info/wordpress/wpnavmenu-adding-class-to-the-all-last-items/
Hope it helps.
I am unfamiliar enough(without being unlazy and researching) with the functions above to figure out how to apply a class to the first child as well. I am working on a menu with end caps that are different from the middle list items.
Right now I’m using the available add custom classes option in the Menu setup, but fear someone breaking the menu due to not knowing what to do.
Any help appreciated :)
Hi Michael, strripos finds the last occurrence of the target string so if you replace it with stripos, you should be laughing. Something like:
function add_first_item_class($strHTML) {
$intPos = stripos($strHTML,'menu-item');
printf("%s first_item %s",
substr($strHTML,0,$intPos),
substr($strHTML,$intPos,strlen($strHTML))
);
}
Hope that helps…
I needed something like this, only then a first and last item for each sub-menu, for making it easier to add rounded corners in css. So made a custom version of this:
/* Add a first and last list item */
function add_last_item_class($strHTML) {
if (preg_match_all('/(.*)/Uis', $strHTML, $return)) {
for($i=0; isset($return[1][$i]); $i++) {
$submenu = "\n\t" . $return[1][$i] . "\t\n";
$strHTML = str_replace($return[0][$i], $submenu, $strHTML);
}
}
echo $strHTML;
}
add_filter('wp_nav_menu','add_last_item_class');
Hi, really useful script, however I’m now needing it to apply an inline style to the class=” and not to the id att which your script seems to do.. any ideas? thanks.
Hi just to say I sorted my problem.. I didn’t realise in WP 3 you can assign your own class to any menu item form the ‘screen options’ when in the menu page in the backend. (sweet!)
I’m not using English as my major language, but all I can say is “Great Post” !!!
Great work:)
I’m using CSS to do that trick.
.menu li:first-child{
…
}
.menu li:last-child{
…
}
best regards
@Pawiksd
Not all versions of Internet explorer support child selectors.
Great post but i use the solution of @Pawiksd and, for me, is faster and easier.
Anyway, good tips.
I am always searching online for articles that can help me educate myself. Looking forward to another great post. Thanks
Wouldn’t you agree, that this is much cleaner:
function add_last_item_class( $items ) {
$items[count($items)]->classes[] = 'last';
return $items;
}
add_filter( 'wp_nav_menu_objects', 'add_last_item_class' );
Hi Konstantin, Yes it is clean code, nice work.
Although it could get called quite a few times in an execution, not that this would be an issue with most WP builds.
Thanks John, worked great, much more reliable than using :last-child pseudo class.