Highlighting wp_nav_menu() Ancestor Class w/o Children in Nav Structure?

There’s a simpler solution. Forget creating pages for each post type just so you can have nav items, because as you have learned, WP has no way of recognizing that the custom types you are browsing are related to that page.

Instead, create a custom link in Appearance->Menus. Just put the URL that will return your custom type and give it a label, then press “Add to Menu”.

http://example.com/workshops/

or non-pretty-permalinks:

http://example.com/?post_type=workshops

this alone will simply create a nav button which displays all posts with that custom post type, and will also add the current-menu-item class when you’ve clicked that nav item – but it won’t yet add the nav class on any URL other than this one

Then, once it’s created, go into the configuration for that new item, and enter the slug of the custom post type in the “Title Attribute” field (you could also use the description field, but that one is hidden in the admin screen options by default).

Now, you need to hook the nav_menu_css_class filter (which gets fired for each nav item) and check if the content being viewed is of the post type indicated in your custom nav item:

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_query_var('post_type');
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

In this case, we’re going to check that the Title Attribute field contents aren’t empty and if they match the current post_type being queried. If so, we add the current-menu-item class to its class array, then return the modified array.

You could modify this to simply match the title of the nav item, but if for some reason you want to title the nav item differently than the plain slug of the post type, using the Title Attribute or Description field gives you that flexibility.

Now any time you’re viewing a single item (or probably even archive listings) of a post type that matches a nav menu item, that item will be given the CSS class current-menu-item so your highlighting will work.

No pages or page templates needed 😉 The URL query takes care of fetching the right posts. Your loop template takes care of displaying query output. This function takes care of recognizing what’s being shown and adding the CSS class.

BONUS

You can even automate the process using wp_update_nav_menu_item, by having menu items automatically generated for all your post types. For this example, you would need first to have retrieved the $menu_id of the nav menu you want this items added to.

$types = get_post_types( array( 'exclude_from_search' => false, '_builtin' => false  ), 'objects' );
foreach ($types as $type) {
    wp_update_nav_menu_item( $menu_id, 0, array(
        'menu-item-type' => 'custom',
        'menu-item-title' => $type->labels->name,
        'menu-item-url' => get_bloginfo('url') . '/?post_type=" . $type->rewrite["slug'],
        'menu-item-attr-title' => $type->rewrite['slug'],
        'menu-item-status' => 'publish'
        )
    );
}

Leave a Comment