How To Highlight Current Category In WordPress Menu (wp_nav_menu) For Single Post Pages Using jQuery

UPDATE 10-11-2010: This information below is dated. The easiest way to accomplish this is to now just use built in classes outputted by WordPress (ie .current-post-parent). Please see this post for more information.

The new menu manager in WordPress 3.0+ is a great addition, and something that is extremely useful for clients. However in certain spots it’s not very intuitive how you get the current page/post/object highlighted.

One of those scenarios is on single post pages. By default the new menu manager will output a class of “.current-menu-item” for a category navigation link only when you are  actually navigating a category landing page, and not on single post pages assigned to that category.

I figure I could approach the solution to this in two ways. I  could try to modify the output of wp_nav_menu itself via the WordPress API or I could do it after the fact, on the client side via jQuery.

From what I’ve read regarding the first option, there actually aren’t many places to hook into this menu and thus may require the use of my own “walker class.”

Using a walker class is a new concept to me, so this probably would require a fair amount of work. Much more than I was willing to do just to highlight the current category. A far easier solution in my opinion is just to go with  the jQuery option and do this on the front-end.

So I came up with this quick solution…

1.  Link up jQuery in your WordPress header.php template, if not already there…

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>

<script type="text/javascript">
  $(document).ready(function() {
    // Your jQuery  here
  });
</script>

2. On your single post template (single.php) dump out the category name somewhere in the HTML (that later can be picked up with jQuery).

In my case I added a “title=” attribute to the #post-xx DIV.

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?> title="<?php $category = get_the_category(); echo $category[0]->cat_name; ?>">

Just to be clear, the part that I added was…

title="<?php $category = get_the_category(); echo $category[0]->cat_name; ?>

I should note, this is actually only dumping out the first category (a WordPress post can have multiple categories of course). The way I  setup sites around categories, usually there is a 1:1 relationship between posts and categories.

If you did have  multiple categories for a post, I’m not sure highlighting multiple “current categories” would be that  important to you (perhaps you’re better off leaving it how it is).  If you really do want to highlight multiple categories in the navigation, this same concept will work, but you’ll have to tweak the code a bit.

3. Use jQuery to store the category name as a variable and then apply the appropriate class in the navigation.

$(document).ready(function() {

var active_cat_name = $("body.single div.post").attr("title");

$("ul.menu li.menu-item-object-category a").filter(function(index) {
 return $(this).text() == active_cat_name; }).parent().addClass("current-menu-item");

});

Let’s look at each line separately…

var active_cat_name = $("body.single div.post").attr("title");

Here we are setting the variable “active_cat_name” equal to the assigned category name from the “title=” attribute we dumped into the HTML in step #2.

Note the use of “body.single div.post” to specifically target the appropriate DIV on single pages. Depending on how your templates are setup, the actual selector my be slightly different.

$("ul.menu li.menu-item-object-category a").filter(function(index) {
 return $(this).text() == active_cat_name; }).parent().addClass("current-menu-item");

In this line we are selecting any menu generated by wp_nav_menu (ul.menu) and scanning the anchor text for the category name. If there is a match the class of “current-menu-item” is added to the parent list item.

Note the use of “li.menu-item-object-category” in the selector which limits this to only categories in the navigation.

4. Create styles in your CSS file to highlight the current state

.current-menu-item { background-color: red; } 

And you’re done!

One quick caveat: This does a match via the “category name” because the wp_nav_menu does not output the category ID. Technically, in WordPress, it is possible to have more than one category with the same name (and different slugs). A better solution may be to use the same concept but in step 2 dump out the category slug into the HTML , and then in step 3, assuming permalinks are on, scan the anchors href instead of the anchors text for a match.

This entry was posted in jQuery, Tips & Tricks, Wordpress. Bookmark the permalink.

3 Responses to How To Highlight Current Category In WordPress Menu (wp_nav_menu) For Single Post Pages Using jQuery

  1. Hi!

    Did you tried set some css rules to match the classes generated by wp_nav_menu function?

    .current-menu-item { } targets only the menu item the visitor pressed to get to the menu. This goes for categories as well as pages.

    .current-page-item { } targets only the current menu item if that menu item is pointing to a page and the visitor is on that page.

    .menu-item-home { } targets only the menu item that points to the root or home page of the site.

    .current-post-ancestor { } targets the menu item as long as the category the menu item points at is an ancestor of the post (so regardless of whether the post is in the category or in a sub-category under the category)

    .current-menu-parent { } targets the menu item if it is the parent of the menu to which the post belongs (yes, it’s confusing).

    .current-post-parent { } targets the menu item only if the category is the direct parent of the post (menu item will not be highlighted if the post only belongs to a category that is a child of the category the menu item points to).

    from: http://www.designisphilosophy.com/tutorials/highlight-current-page-or-category-20100809/

    • thecitizen says:

      Thanks you’re exactly right. I think that’s something that wasn’t implemented when I originally wrote this post (WP3 was still in beta at the time). I’ll make an update at the top of this post. Using the pre-built classes is the way to go.

  2. ismael says:

    very usefull.
    many tks

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>