wordpress

Wordpress: Highlight "Blog" Menu Item on all Blog Pages

Most WordPress themes highlight the current menu item, so does my current theme Inovado. While the highlighting works very well on static pages, it has a counterintuitive behaviour on blog pages: the corresponding menu item is only highlighted if on the root page. As soon as one visits a single blog post or filters by category, tag or date, the highlight disappears.

Fix

There are many workarounds to get the blog menu highlighted on all blog related pages, but most of them didn’t work for me. Here’s a solution that has the desired effect:

*Edit: At some point a closing bracket went missing, thanks Shiraz for pointing that out.*

function add_custom_class($classes=array(), $menu_item=false) {
    if ( !is_page() && 'Blog' == $menu_item->title && 
            !in_array( 'current-menu-item', $classes ) ) {
        $classes[] = 'current-menu-item';        
    }                    
    return $classes;
}
add_filter('nav_menu_css_class', 'add_custom_class', 100, 2); 

Change the test $menu_item->title == ‘Blog’ in line 2 according to the label of your blog menu item. Then add the snippet to functions.php. (You can also download the code from GIST).

How does the fix work?

The highlight for menu items is triggered by the CSS class current_page_item, e.g., in the following example the menu item “Blog”:

<ul id="nav" class="menu sf-js-enabled">
   <li id="menu-item-35" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-35">
      <a href="http://johannesbader.ch/phd-thesis/">PhD Thesis</a>
   </li>
   <li id="menu-item-36" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-36">
      <a href="http://johannesbader.ch/publications/">Publications</a>
   </li>
   <li id="menu-item-867" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-867">
      <a href="http://johannesbader.ch">Blog</a>
   </li>
</ul>

The code registers a new filter with add_filter(‘nav_menu_css_class’, ‘add_custom_class’, 100, 2); which will be triggered by the WordPress hook nav_menu_css_class. The hook runs when the navigation menu’s CSS classes are built. The second argument of add_filter is the (arbitrary) name of the callback function. The third argument determines the priority (don’t now exactly what priority does). The fourth argument corresponds to the number of arguments of the callback function.

The callback function add_custom_class($classes=array(), $menu_item=false) has two arguments. The first is an array to which the function adds class names that should be appended to the menu item. The second argument is the processed menu item (the callback function will be called once for each menu item). We only want to highlight the “blog” menu item, hence the test $menu_item->title == ‘Blog’. Furthermore, the blog menu item should only be highlighted if we are actually on a blog post, i.e., NOT on a static page. That’s what the test !is_page() is for. The last test !in_array( ‘current-menu-item’, $classes ) is to make sure that the CSS class is not added more than once. If all those conditions apply, we set the $classes[] to ‘current-menu-item’.

Archived Comments

Note: I removed the Disqus integration in an effort to cut down on bloat. The following comments were retrieved with the export functionality of Disqus. If you have comments, please reach out to me by Twitter or email.

HalfofW Dec 12, 2013 03:22:34 UTC

Thank, works on my local WP3.6 install. Will give it a try a soon as my page is online

Shiraz Feb 25, 2014 09:16:45 UTC

I added the code to my functions.php however, this would cause my entire wordpress to fail. Front-end would give the error: "Parse error: syntax error, unexpected end of file in /home/sarahggg/public_html/dev/wp-content/themes/twentytwelve/functions.php on line 547"

I am running WP 3.8.

Any ideas?

Johannes Feb 25, 2014 13:40:00 UTC

The closing } of the if statement was missing in code excerpt (the GIST was correct though). Please try again with the revised snippet.

Thanks for pointing out the error and sorry for the inconvenience.

Star Mar 29, 2014 02:29:18 UTC

Thank you so much for posting this. It is the first solution that worked for me for my main navigation menu. I have one followup question. How would I add an additional submenu item that needs to stay highlighted as current at the same time.

grafx Jul 01, 2014 15:01:32 UTC

Would it not be best to use (for example if the menu id of the blog was 14) ...

if ( !is_page() && $menu_item->object_id == 14 &&

instead of

if ( !is_page() && 'Blog' == $menu_item->title &&

Just incase you rename the Blog.

Johannes Jul 01, 2014 15:11:07 UTC

Yes, your version is probably better because you can safely rename "Blog" without breaking the code. On the downside, you can't rebuild the menu as the object_id might change.

begs Aug 04, 2015 07:36:43 UTC

the menu title solution ("Blog") is much better. the menu title doesn't really change and if, than not often. but if you got a development and production environment, your page ids may differ. that makes it a pain because you'd have to differentiate between off and online in your functions.php.

ST Sep 23, 2014 22:35:28 UTC

Hi,

I just want to say thank you.
I've been searching for the solution forever and found this. Your code works beautifully!

begs Aug 04, 2015 07:34:39 UTC

Thanks for that perfect solution. Better than any suggestion i read before on other blogs, because it's flexible and not tied to a specific page id.

Rozumna Holka Nov 09, 2015 20:13:07 UTC

WOW! Thanks!

Alison Jan 12, 2017 15:18:23 UTC

OMG thank you x 1000000!!!!!!!!!
I have tried everything out there and nothing worked for me!
I just had to tweak your statement a tiny bit to accommodate my site, where the menu-item-id of my blog page (which is my renamed home page) is 58:

function add_custom_class($classes=array(), $menu_item=false) {
if ( !is_page() && 58 == $menu_item->ID &&
!in_array( 'current-menu-item', $classes ) ) {
$classes[] = 'current-menu-item';
}
return $classes;
}
add_filter('nav_menu_css_class', 'add_custom_class', 100, 2);

THANK YOU!!!!!!!!!!!!
my site is ninedarkmoons.com

Debendra Maharjan Dec 12, 2018 03:38:40 UTC

THANK YOU

Ai7ch Mar 14, 2019 21:58:03 UTC

just THANK YOU! :-D

Henning M ツ Mar 26, 2019 10:28:05 UTC

Any way that this script can be expanded to work with two blogs on the same site?

I have the following URL structure:
/%category%/%postname%/

Thanks!