I’m using a WordPress Menu to create a navigation structured like this:
- Home
- About
- Contact
- Sub Page
Using this code from kuroi’s response here I’m able to add first-menu-item
and last-menu-item
classes to the list items above:
function add_first_and_last($output) {
$output = preg_replace('/class="menu-item/', 'class="first-menu-item menu-item', $output, 1);
$output = substr_replace($output, 'class="last-menu-item menu-item', strripos($output, 'class="menu-item'), strlen('class="menu-item'));
return $output;
}
add_filter('wp_nav_menu', 'add_first_and_last');
However the last-menu-item
class is being added to the Sub Page list item (because it’s the last) rather than to the Contact list item.
Question: How can I make this function apply only to the top level items of a menu?
Thanks!
5 Answers
I would lean very much towards a custom walker for this but I think I’ve managed to make it work using part of that code and some of my own.
function add_position_classes_wpse_100781($classes, $item, $args) {
static $fl;
if (0 == $item->menu_item_parent) {
$fl = (empty($fl)) ? 'first' : 'middle';
$classes[] = $fl.'-menu-item';
}
return $classes;
}
add_filter('nav_menu_css_class','add_position_classes_wpse_100781',1,3);
function replace_class_on_last_occurance_wpse_100781($output) {
$output = substr_replace(
$output,
'last-menu-item ',
strripos($output, 'middle-menu-item'),
strlen('middle-menu-item')
);
return $output;
}
add_filter('wp_nav_menu', 'replace_class_on_last_occurance_wpse_100781');
What I did was add first-menu-item
and middle-menu-item
to top level items only with the first filter on nav_menu_css_class
. Then with the second filter I replaced the last occurrence of middle-menu-item
with last-menu-item
.
It works for the few test cases I tried.