wp_nav_menu doesn’t generate parent/ancestor classes

I don’t know why the proper classes for menu item are not generated – all the elements in the tree which has subtree get only menu-item menu-item-type-post_type. The elements, which don’t have children, get proper classes after being clicked (active).

Link: http://lichens.ie/

Read More

Part of the menu structure: http://imgur.com/5Lj00.png

Code

$args = array(
    'menu'      => 'Main menu',
    'container' => '',
    'menu_id'   => 'nav',
);
wp_nav_menu($args);

When you visit e.g. http://lichens.ie/view-lichens-by/lichens-by-habitat/ you can see that it has no ‘current’ class. As well as it’s parent.

PS Sorry for posting ‘not working links’ – it’s because of reputation limitation

Any ideas – help much appreciated.

Related posts

Leave a Reply

2 comments

  1. This is part of code in _wp_menu_item_classes_by_context() that handles current class for pages:

    // if the menu item corresponds to the currently-queried post or taxonomy object
    } elseif (
        $menu_item->object_id == $queried_object_id &&
        (
            ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && $wp_query->is_home && $home_page_id == $menu_item->object_id ) ||
            ( 'post_type' == $menu_item->type && $wp_query->is_singular ) ||
            ( 'taxonomy' == $menu_item->type && ( $wp_query->is_category || $wp_query->is_tag || $wp_query->is_tax ) )
        )
    ) {
        $classes[] = 'current-menu-item';
    
    1. IDs must match.
    2. It must be of post_type type.
    3. Query should be for is_singular.

    Second point can be excluded, because CSS class for item type is generated correctly. So something goes wrong either with IDs or is_singular conditional.

    Are you running any secondary loops on page? Most common reason for conditionals to break is improper use of query_posts().

  2. I don’t know why its not working in your case… Like you say, the active page should be getting ‘current_menu_item’ added to its classes. If you’re having trouble for one reason of another, you can always use the ‘nav_menu_css_class’ filter to add your own classes. This little bit of code will essentially duplicate the ‘current_menu_item’ & ‘current_menu_parent’ classes, and add a ‘has_children’ class (useful for expandable or dropdown menus):

    function check_for_submenu($classes, $item) {
        global $wpdb, $post;
        if ($item->ID == $post->ID) array_push($classes,'current_menu_item');
        $has_children = $wpdb->get_var("SELECT COUNT(meta_id) FROM wp_postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value='".$item->ID."'");
        if ($has_children > 0) {
            array_push($classes,'has_children');
            $child_pages = $wpdb->get_col("SELECT c.meta_value FROM wp_postmeta AS c, wp_postmeta AS th 
                                          WHERE c.meta_key = '_menu_item_object_id' AND c.post_id = th.metavalue 
                                          AND th.meta_key= '_menu_item_menu_item_parent' AND th.post_id = {$item->ID}");
            if (in_array($post->ID,$child_pages)) array_push($classes,'current_menu_parent');
        }
        return $classes;
    }
    
    add_filter( 'nav_menu_css_class', 'check_for_submenu', 10, 2);
    

    Of course you want to figure out why the built-in functionality isn’t working for you before hacking up something to duplicate it, but you can do a lot with that filter if necessary…