March 11, 2025 in Wordpress

How to Fix WordPress Menu Highlighting for Custom Post Types

If you’ve ever created a custom post type (CPT) in WordPress, you may have noticed an issue where your navigation menu incorrectly highlights the Blog menu item instead of the correct one. This happens because WordPress assigns the current_page_parent class to the blog menu by default when viewing single posts—including custom post types.

In this guide, we’ll show you how to fix this issue by dynamically assigning the correct menu item highlighting for custom post types using a simple PHP function in functions.php.

Use Case: Why Fixing Menu Highlighting Matters?

Let’s say you have two custom post types:

  • event (for listing events)
  • initiative (for showcasing initiatives)

You also have corresponding menu items:

  • Events (/events/)
  • All Initiatives (/all-initiatives/)

However, when you click on an event, the navigation does not highlight the “Events” menu item. Instead, the Blog menu gets highlighted because WordPress treats it as a regular post.

We’ll fix this by ensuring the correct menu item gets the current_page_item class whenever a user views an event or initiative post or their archives.

The Code Solution

Add the following code to your functions.php file:


function fix_custom_post_type_menu_highlight($classes, $item) {
    // Define custom post types and their corresponding menu item slugs
    $menu_mappings = [
        'event' => 'events',  // Custom post type 'event' should highlight 'events' menu item
        'initiative' => 'all-initiatives', // Custom post type 'initiative' should highlight 'all-initiatives' menu item
    ];

    foreach ($menu_mappings as $post_type => $menu_template) {
        if (is_singular($post_type) || is_post_type_archive($post_type)) {
            // Remove incorrect highlighting from the Blog menu item
            if ($item->object_id == get_option('page_for_posts')) {
                $classes = array_diff($classes, ['current_page_parent']);
            }

            // Ensure we don't add duplicate classes
            $classes = array_filter($classes, function($class) {
                return !in_array($class, ['current_page_item', 'current-menu-item']);
            });

            // Apply 'current_page_item' to the correct menu item
            if (stripos($item->url, '/' . $menu_template) !== false) {
                $classes[] = 'current_page_item';
            }
        }
    }

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

How This Code Works

1. Define the Custom Post Type Mappings

$menu_mappings = [
    'event' => 'events',
    'initiative' => 'all-initiatives',
];
  • This array maps custom post types (event, initiative) to their corresponding menu item slugs (events, all-initiatives).
  • Update this array to include more CPTs and menu items as needed.

2. Check if the User is on a CPT Page

if (is_singular($post_type) || is_post_type_archive($post_type)) {
  • This checks if the user is viewing a single post from a CPT or the CPT archive page.

3. Remove Incorrect Highlighting from the Blog Menu

if ($item->object_id == get_option('page_for_posts')) {
    $classes = array_diff($classes, ['current_page_parent']);
}
  • If the menu item is the Blog page, we remove the current_page_parent class (which WordPress applies incorrectly).

4. Prevent Duplicate Classes

$classes = array_filter($classes, function($class) {
    return !in_array($class, ['current_page_item', 'current-menu-item']);
});
  • This ensures we don’t add multiple active classes, keeping the HTML clean.

5. Apply the Correct Highlighting to the CPT Menu Item

if (stripos($item->url, '/' . $menu_template) !== false) {
    $classes[] = 'current_page_item';
}
  • This checks if the menu item URL contains the correct slug (e.g., /events/) and applies the current_page_item class.

Final Output: Expected Behavior

After adding this function:

  • When viewing an event post or archive, the “Events” menu item is highlighted.
  • When viewing an initiative post or archive, the “All Initiatives” menu item is highlighted.
  • The Blog menu item is no longer highlighted incorrectly.

Conclusion

This solution ensures that your WordPress menu correctly highlights custom post types instead of mistakenly marking the Blog menu as active. It’s a reusable function, so you can easily extend it by adding more CPTs to $menu_mappings.

Try it out and make your WordPress menus more intuitive!

About the author

Alok Jain

As a Frontend Developer and Founder, I blend technical skills with entrepreneurial drive. Skilled in crafting intuitive user interfaces, I bridge design and development for seamless digital experiences. Beyond work, I'm passionate about Philately, sharing my collection, and connecting with fellow enthusiasts in both tech and stamp collecting communities.

Leave a Reply

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