Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Working on a theatrical events site. The structure requires several separate events areas, each with a top page listing events in the particular area, and corresponding individual events pages underneath the listings page. Since each of the event area pages require a different treatment, I thought this was a good situation for custom post types, using both single-[event] and archive-[event] templates for each area.

I installed Custom Post Types UI to make the custom post types (including matching custom taxonomy) and Advanced Custom Fields to make meta fields. So far so good. The Archive custom post type (full listing of area events) pulls meta from the Single custom post type, and both custom post pages display correctly except for one thing: the main nav menu no longer highlights the active web page on the Archive listing. [Note: there are many posts about how to highlight submenu Single custom posts to match parent; I don’t need that, just need the current Event Area to highlight correctly in main menu nav!]

I realized I had constructed my main nav – which includes the event areas – with wp_nav_menu and register_nav_menus. So the event areas corresponding to Archive custom posts were originally constructed as Pages and the main nav was set up using WP Menu’s drag and drop capability. Wordpress correctly defaults to the archive-[event] custom post template (and ignores the existing Page with same name), and the nav menu is functional in terms of links, but doesn’t highlight the Archive custom post link in the nav. Pages in the main nav work correctly.

When I check output on Event Area, there is a “current_page_parent” class attached to the Blog nav, but no “current-menu-item” elsewhere, which I guess is appropriate for custom posts. I suppose if wp_nav_menu is just for Pages, this makes sense as the top-level archive posts won’t be recognized, but I have no clue how to fix it. I’m will to try hacks, but want to avoid ID-specific ones or jQuery if possible. One thought would be to chuck the archive-[event] template, and use a regular page template for the listing while keeping the true single-[event] custom type post. Any reason faking it that way couldn’t work? Thanks for any advice, hope I'm missing obvious/easy approach.

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

I have always considered this a bug, but if not, it's pretty disconcerting. You have 2 things to fix: the first is to not highlight the "Blog" top-level item, and the second is to highlight the appropriate top-level item under which your single CPT resides.

There might be other methods, but I'll share my method, which unfortunately, DOES target the menu ID's with CSS.

To the nav container, add a conditional that identifies when the nav is being displayed on the single CPT:

<nav class="navsf<?php if (is_singular('news')) { echo ' fixhilite'; } ?>">

Then you'll need to get the id's for the "Blog" menu item and for the CPT parent Menu Item (in this example, "News"). Let's say for "Blog" it's the following:

<li id="menu-item-29" ...>

And for "News" it's:

<li id="menu-item-30" ...>

In your CSS, you might target these items like so to change text or background colors to highlight/un-highlight things accordingly:

.navsf.fixhilite li#menu-item-29

.navsf.fixhilite li#menu-item-30

share|improve this answer
    
Thanks for the suggestion. I came up with a similar ID-based hack, so I guess that's an answer for now. I have actually tested a solution that's non-ID specific and seems to work, which can be found here: modal.us/blog/2011/04/28/… That noted, WordPress really needs to add/generalize this capability, it's just too common a scenario. –  boomturn Apr 6 '12 at 5:43
    
Agreed. This is something I think should "just work", with "current-page-ancestor" automatically applied to the parent list item. –  Ray Gulick Apr 6 '12 at 14:01
add comment

your problem is probably solved already long time ago. Anyway, here is may solution:

public static function WPFilter_UpdateNavMenuCSS($classes, $item) {
    $pages = get_posts ( array (
                                'post_type' => 'page', 
                                'meta_key' => '_wp_page_template', 
                                'meta_value' => 'page-works.php' ) );
    if (is_array ( $pages ) && count ( $pages ) > 0) {
        $root_page = $pages [0];
        if (is_singular ( self::id )) {
            if (( int ) $root_page->ID == ( int ) $item->object_id) {
                $classes [] = 'current_page_parent';
            } else {
                $key = array_search ( 'current_page_parent', $classes );
                if ($key) {
                    unset ( $classes [$key] );
                }
            }
        }
    }
    return $classes;
}

Just modify this method according your needs. You have to replace page-works.php and self:id accordingly.

For next you have to register filter to call method defined above:

add_filter ( 'nav_menu_css_class', 'SimpleTheme\PostType\Portfolio::WPFilter_UpdateNavMenuCSS', 10, 2 );

This solution requires that you have a custom page template to show list of your custom post type and this template is chosen for page, which you want define as parent page.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.