6

I'm trying to remove current_page_parent class from the blog index menu item (I got a custom page to display all blog posts and it is in the menu) when navigating custom post type archive page and custom post type posts.

I've found similar questions but I can't figure out how to solve it. In addition, I don't have the current_page_parent when navigating the custom_post_type (I guess it is related).

4 Answers 4

11

You can use the nav_menu_css_class filter to add or remove classes from menu items. Each individual menu item will have this filter applied. An array of classes and the menu item object will be passed to the function, and you will return an array of the classes you want the menu item to have.

PHP's array_diff can be used to remove classes, and adding items can be accomplished by appending class names to the array via $classes[] = 'some-class-name'. You can use the Conditional Tags to check what sort of page is currently being viewed to determine what you need to add or remove.

Here's a quick example that checks if the page currently being viewed is either an archive or single post of the type your-post-type, and the menu item name is Blog. If those conditions are met, the current_page_parent class is removed from the array of classes for that menu item. You can add to or tweak this for your needs.

function wpdev_nav_classes( $classes, $item ) {
    if( ( is_post_type_archive( 'your-post-type' ) || is_singular( 'your-post-type' ) )
        && $item->title == 'Blog' ){
        $classes = array_diff( $classes, array( 'current_page_parent' ) );
    }
    return $classes;
}
add_filter( 'nav_menu_css_class', 'wpdev_nav_classes', 10, 2 );
4
  • Thank you very much, it solved my problem, teached me a bit of php and how to handle menu classes in the future. Oct 26, 2015 at 16:11
  • Awesome, solves my scenario too.
    – Den Isahac
    Jul 13, 2017 at 19:04
  • This helped me out, but why is the custom post being recognised as a child of the blog page? May 4, 2018 at 10:46
  • This solved my issue of the blog page being highlighted as current page on the cpt archive page when there were no active posts of the cpt (which prompts me to ask what Alexander did above — why is it considered a child page of blog?). I'm using Sage, so I ended up also removing 'active' as well as making sure the cpt nav item had 'active' added to it. Clunky, but it worked.
    – Nate Beaty
    May 22, 2019 at 16:26
6

The current answer is great but it assumes the title of blog's navigation item is "Blog". This could cause problems if the a user ever modifies the nav item in WordPress. The following code is universal as it compares the page id of the nav item against the page id of the blog stored in WordPress options.

function my_custom_post_type_nav_classes( $classes, $item ) {
    $custom_post_type = 'custom-post-type';
        if( ( is_post_type_archive( $custom_post_type) || is_singular( $custom_post_type ) )
        && get_post_meta( $item->ID, '_menu_item_object_id', true ) == get_option( 'page_for_posts' ) ){
            $classes = array_diff( $classes, array( 'current_page_parent' ) );
        }
        return $classes;
    }
    add_filter( 'nav_menu_css_class', 'my_custom_post_type_nav_classes', 10, 2 );
3

Ok both answers are not very elegant because you have to enter the CPTs name manually. Here is a simple drop in snippet. It is pretty much copied from here so kudos to that site.

This snippet removes the current_page_parent class of the blog menu item:

add_filter( 'nav_menu_css_class', 'theme_remove_cpt_blog_class', 10, 3 );

function theme_remove_cpt_blog_class( $classes, $item, $args ) {


    if( !is_singular( 'post' ) AND !is_category() AND !is_tag() AND !is_date() ):

        $blog_page_id = intval( get_option( 'page_for_posts' ) );

        if( $blog_page_id != 0 AND $item->object_id == $blog_page_id )
            unset( $classes[ array_search( 'current_page_parent', $classes ) ] ); 

    endif;


    return $classes;


}

Altough it wasn't asked primarily i think when removing the class from the blog menu item in most cases you want a class to highlight the CPTs archive menu item so here is a snippet for that too.

This snippet adds a current_page_parent class on the archive menu item of a CPT:

add_action( 'nav_menu_css_class', 'theme_add_cpt_ancestor_class', 10, 3 );

function theme_add_cpt_ancestor_class( $classes, $item, $args ) {


    global $post;

    $current_post_type = get_post_type_object( get_post_type( $post->ID ) );

    if ( $current_post_type === 'post' ) {
        return $classes;
    }

    $current_post_type_slug = is_array( $current_post_type->rewrite ) ? $current_post_type->rewrite['slug'] : $current_post_type->name;

    $menu_slug = strtolower( trim( $item->url ) );

    if( strpos( $menu_slug, $current_post_type_slug ) !== false )
        $classes[] = 'current_page_parent';

    
    return $classes;


}
0

I build custom template page instead of using custom post type archive default pages. And I faced that issue too. When I was on that custom template pages, or in the CPT single pages, I had the Blog menu item that was highlithed, as if there were all children of the Blog page.

I finaly used the functions mentioned by GDY and it works great. Thank you !

But I still don't understand why suddenly and what in the code make the blog menu item to highlight when on a custom page or CPT.

Does someone have the answer ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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