We know that when we access a WordPress URL, WordPress will automatically add the “current-menu-item” class to this URL in the navigation menu items to help frontend developers perform highlighting. When we have multiple post types, when accessing the single post page of a post type, we sometimes need to also add the “current-menu” class to the archive page of that post type. For example, when visiting http://abc.com/box/small-box, we want to add the “current-menu-item” class to the archive page http://abc.com/box/ for that post type; WordPress doesn’t support this feature by default. In a strictly semantic sense, the single post page and the post type archive page are not the same page, but from a user experience perspective, this operation makes sense.
Adding the Current Menu Class to the Post Type Archive Page Using the nav_menu_css_class Action Hook
We can achieve this requirement by comparing the post type slug and the URL string. Below is the implementation code; this method is not very strict and might have bugs in special cases.
add_action('nav_menu_css_class', function ($classes, $item)
{
// Get the current post
global $post;
// Get the post type of the current post
$current_post_type = get_post_type_object(get_post_type($post->ID));
$current_post_type_slug = $current_post_type->rewrite[ 'slug' ];
// Get the URL of the navigation menu item
$menu_slug = strtolower(trim($item->url));
// If the menu item contains the current post type's slug, add the current menu CSS class
if (strpos($menu_slug, $current_post_type_slug) !== false) {
$classes[] = 'current-menu-item';
}
// Return the modified CSS class data
return $classes;
}, 10, 2);
Note: The code above is only effective when fixed link structures are set to “post name”; for other situations, you can refer to the code above and test it yourself.
Possible Bugs and Solutions
Let’s imagine this situation: a post type name is “box,” and the website address is www.express-box.com. In this case, the website’s URL always contains “box.” When we open the details page of the box post type, all menu items will have a current menu class added.
When comparing URLs, excluding the domain name part of the address can reduce the probability of this bug occurring. According to the structural characteristics of WordPress URLs, the post type slug is displayed immediately following the domain name. We can use regular expressions to match this post type slug from the website address and then compare it with the post type slug obtained via the post object.
Besides adding the current menu class to the post type archive URL of the current post, we can also use a similar method to add the current menu class to the categories or custom taxonomy terms the current post belongs to. Due to time limits, I won’t test the corresponding code one by one; I’ll add it later when I have time. If you’ve written the corresponding code, feel free to post it in the comments for everyone’s reference.
