Add Ancestor Class to Navigation Menus For Single Posts (Blog Posts and Custom Post Type Posts)

Home » Blog » WordPress Development » Add Ancestor Class to Navigation Menus For Single Posts (Blog Posts and Custom Post Type Posts)


If you have a link to a category in your navigation menu, you can add a class to that category link whenever a post (single post) of that category is being displayed. This lets your user know which section of the site they are in and what category this post belongs to.
To do this, all you need to do is add the following code to your theme’s function.php file or to a custom plugin:

<?php
/*
Adds a custom CSS class to category links in navigation menus if the post displayed is of the same category.
*/
// This function is called for every link item in every navigation menu.
function add_ancestor_class_to_nav_menu_item($classes, $item){
    global $post; // Get a reference of the current post
    $is_ancestor = false;

    if ( is_single() ) {
        // Check if the current post is a custom post type. Any post that isn’t of type ‘post’ is a custom post type post.
        if ( $post->post_type !== 'post' ) {
            $post_type_obj = get_post_type_object($post->post_type); // Get the custom posts type.
            $post_type_labels = $post_type_obj->labels;
            $post_type_name = $post_type_labels->name;
            if( $item->title === $post_type_name )
                    $is_ancestor = true;
        }
        else {
            // A post can have multiple categories.
            // Get a list of every category this post has and check it against the current menu item.
            $categories = get_categories();
            foreach ( $categories as $category ) {
                // If the name of the current category is the same as the name of this NAV item’s title, then this single post is a child of this category.
                if ( in_category($category->name) && $item->title === $category->name )
                    $is_ancestor = true;
            }
        }
        if($is_ancestor)
                $classes[] = 'current-page-ancestor';
    }

    return $classes;
}
add_filter('nav_menu_css_class',  'add_ancestor_class_to_nav_menu_item', 10 , 2);

The above code adds a filter function to the nav_menu_css_class filter. This function will be called right before a class is added to the nav menu links. This function then checks if the current page is a single post page using the is_single function.
This code then checks the type of post and checks if the post’s category or label is the same as the name of the current link. If it’s the same, then it means this current post is a descendent of this category link.
If you are using this code, make sure to use the same name for your navigation menu link as the name of your category. If the name of the navigation link to the category page is different than the name of the category, this code won’t work!

Leave a Reply

Your email address will not be published. Required fields are marked *

Register an account to save your snippets or go Pro to get more features.