Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Highlighting current nav on single.php using wp_nav_menu WordPress

  • SOLVED

I have wp_nav_menu working perfectly, with 2 exceptions, both related to single.php:

1) Using the regular post type to hold 'thoughts' - if the current single.php is not in category 331, 332 or 333, then add the 'active' class to the main parent nav LI. This works for the various category archives ('thoughts' has the correct active class), but not for the single posts.

2) A second post type of 'mediamentions', with their own custom single-mediamentions.php - if one of these is being viewed, I need to add an 'active' class to the '/about' nav item.

I'd really rather use wp_nav_menu than have to do this manually, and ideally would like both of these single.php posts to set the active class on the nav correctly. It wouldn't be the end of the world if it doesn't work for mediamentions, but it's really important that they work for 'thoughts'.

Any idea how to implement this?

Answers (1)

2011-05-19

derekshirk answers:

So I've heard of people having a similar problem to this with custom post types and single.php files.

=================================
Solution 1
=================================

A sort of dirty fix that you can add to your functions.php would be:


function remove_parent($var)
{
// check for current page values, return false if they exist.
if ($var == 'current_page_parent' || $var == 'current-menu-item' || $var == 'current-page-ancestor') { return false; }

return true;
}

function tg_add_class_to_menu($classes)
{
//use your Custom Post Type name here
if (is_singular('custom_post_type_here'))
{
// we're viewing a custom post type, so remove the 'current-page' from all menu items.
$classes = array_filter($classes, "remove_parent");

// add the current page class to a specific menu item.
if (in_array('menu-item-239', $classes)) $classes[] = 'current-page-ancestor';
}

return $classes;
}

if (!is_admin()) { add_filter('nav_menu_css_class', 'tg_add_class_to_menu'); }


The downside to using this method is you are using an ID to decide which menu item to add the current class to, so if you delete/readd a page you will have to edit this code.


=================================
Solution 2 -- if the first option doesn't work try this:
=================================


// Menu Fix for CPT
function remove_parent($var)
{
// check for current page values, return false if they exist.
if ($var == 'current_page_item' || $var == 'current_page_parent' || $var == 'current_page_ancestor' || $var == 'current-menu-item') { return false; }

return true;
}

function add_class_to_cpt_menu($classes)
{
// your custom post type name
if (get_post_type() == 'custom_post_type_name_here')
{
// we're viewing a custom post type, so remove the 'current_page_xxx and current-menu-item' from all menu items.
$classes = array_filter($classes, "remove_parent");

// add the current page class to a specific menu item.
if (in_array('menu-item-xx', $classes)) $classes[] = 'current_page_parent';
}


Jon comments:

Hey Derek - thanks for this.

We're cool with using the ID in the CSS - that's no biggie. This is working perfectly for mediamentions, but I need to do the same for the regular post type as well?

It would need to do exactly the same thing, but for a different nav item.


derekshirk comments:

Have you tried to use php to id the body id or class of the page yet?

For example you could do something like:


<?php
$url = explode('/',$_SERVER['REQUEST_URI']);
$dir = $url[1] ? $url[1] : 'home';
?>

<body id="<?php echo $dir ?>">


Then you should be able to use the body ID and CSS identifier to have more fine tuned control over the nav element?


derekshirk comments:

I forgot to mention that last suggestion would be placed within your header.php file and replace your <body> tag


Jon comments:

My URL structure is

/CATNAME/SLUG, so that's not a great deal of use - if it could do a quick test for 'is single' and output that, it would work?


Jon comments:

OK, not to worry - I realised I could just pass a variable from single.php and test for this in the header file. All set now - thanks a lot.