Setting Active Nav item (of Pages) when you are on a Post with Category

Well, once I got debugging working, I was able to figure out how this nav_menu_css_class filter works.

First, I parse the url off of the nav item. Then I use that to compare against the post’s category array. If I find a match, I set the $classes[] array, and I’m good to go.

I know parsing the url is a bit ghetto, but I was hoping that the $item would be the target page, but it’s not. It’s just the post that’s created to be in the nav. There is not handle to its target other then the url.

add_filter('nav_menu_css_class', 'post_current_category_class', 10, 2);

function post_current_category_class($classes, $item) {

    // $classes is the list of classes on a nav item
    // $item is the nav item

    if ( is_singular('post') ) {

        $navUrl = $item->url;
        $navParts = parse_url($navUrl);
        $location = ltrim($navParts['path'], "https://wordpress.stackexchange.com/");
        $location = rtrim($location, "https://wordpress.stackexchange.com/");

        $post_category_ids = wp_get_post_categories( $GLOBALS['post']->ID);
        $categories = array();

        foreach($post_category_ids as $c){
            $cat = get_category( $c );
            $categories[] = $cat->slug;
        }

        if (in_array($location, $categories)){
            $classes[] = 'current-menu-item';
        }

    }

    return $classes;
}