How to add "active" class to wp_nav_menu() current menu item (simple way)
I am creating custom Wordpress theme using a starter theme _Underscores and Bootstrap.
I would like to modify wp_nav_menu
so that it assigns the current menu item .active
class instead of the default .current-menu-item
. I need this in order to use .active
class from Bootstrap.
Here is what I have (extra stuff comes from WP so please scroll to the right):
<ul id="menu-main-menu" class="nav navbar-nav">
<li id="menu-item-14" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-13 current_page_item menu-item-14"><a href="">item1</a></li>
<li id="menu-item-12" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-12"><a href="">item2</a></li>
</ul>
And here is what I need:
<ul id="menu-main-menu" class="nav navbar-nav">
<li id="menu-item-14" class="active menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-13 current_page_item menu-item-14"><a href="">item1</a></li>
<li id="menu-item-12" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-12"><a href="">item2</a></li>
</ul>
I would prefer to achieve this without modifying ../wp-includes/nav-menu-template.php
and without using JS.
UPDATE: I found the answer just before posting this question, but since I had a rather hard time finding it, posting this as a QA to hopefully save someone some time.
Just paste this code into functions.php file:
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class ($classes, $item) {
if (in_array('current-menu-item', $classes) ){
$classes[] = 'active ';
}
return $classes;
}
More on wordpress.org:
- Highlight Current Page in WordPress 3.0 Menus
- Adding
.active
class to active menu item
To also highlight the menu item when one of the child pages is active, also check for the other class (current-page-ancestor
) like below:
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class ($classes, $item) {
if (in_array('current-page-ancestor', $classes) || in_array('current-menu-item', $classes) ){
$classes[] = 'active ';
}
return $classes;
}
If you want the 'active' in the html:
header with html and php:
<?php
$menu_items = wp_get_nav_menu_items( 'main_nav' ); // id or name of menu
foreach ( (array) $menu_items as $key => $menu_item ) {
if ( ! $menu_item->menu_item_parent ) {
echo "<li class=" . vince_check_active_menu($menu_item) . "><a href='$menu_item->url'>";
echo $menu_item->title;
echo "</a></li>";
}
}
?>
functions.php:
function vince_check_active_menu( $menu_item ) {
$actual_link = ( isset( $_SERVER['HTTPS'] ) ? "https" : "http" ) . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if ( $actual_link == $menu_item->url ) {
return 'active';
}
return '';
}
In addition to previous answers, if your menu items are Categories and you want to highlight them when navigating through posts, check also for current-post-ancestor
:
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class ($classes, $item) {
if (in_array('current-post-ancestor', $classes) || in_array('current-page-ancestor', $classes) || in_array('current-menu-item', $classes) ){
$classes[] = 'active ';
}
return $classes;
}