Function Friday #6: add a class to the current content’s ancestor in the menu
Every Friday, I’m sharing code snippets that I use to customize WordPress. Feedback/suggestions are always welcome! For more information, check out the first post in the series.
Sometimes a tiny design change can make navigating a website much easier. Indicating which page you’re currently on by changing the style of the corresponding menu item is one of those changes, and WordPress helps you out by adding a bunch of classes to every menu item (as long as you’ve added the menu using wp_nav_menu).
When you view a page that’s listed in the menu, those classes include:
current-menu-item
current_page_item
If you’re viewing a child page of a page that’s in the menu, the relevant class is:
current-page-ancestor
Special classes also get added to the Posts Page (if it’s in your menu) when you’re viewing a single post. For example, you’re looking at a single post right now – if you inspect the “Writing” menu item above, it has this class:
current_page_parent
The current_page_parent class is also applied to the Posts Page menu item if you’re viewing a post archive page (like the category archive for PHP on this site).
This means that whether you’re viewing the Posts Page, a single post (like this one), or a category archive, the “Writing” menu item is always styled the same:
Once you add custom post types into the mix, however, these classes don’t automatically appear on menu items. For example, I have a custom post type called Work with a custom taxonomy called Types on this site. Viewing the custom post type archive adds the class current-menu-item to the “Work” menu item, so it can be styled:
But if you view a single Work post, or the taxonomy archive for Development, the only classes that appear on the “Work” menu item are:
menu-item
menu-item-type-custom
menu-item-object-custom
menu-item-85
The code
// Add current_page_parent class for single portfolio items and archives
function drollic_add_custom_class( $classes = array(), $menu_item = false ) {
if ( ( is_singular('work') || is_tax('types') ) && 85 == $menu_item->ID && !in_array( 'current_page_parent', $classes ) ) {
$classes[] = 'current_page_parent';
}
return $classes;
}
add_filter( 'nav_menu_css_class', 'drollic_add_custom_class', 10, 2 );
This checks whether all of the following conditions are true:
- we’re viewing a single post with the post type Work or a taxonomy archive page for the custom taxonomy Types
- the menu item’s ID is 85 (on my site the menu item “Work” has the ID 85, which you can find by checking the classes for something like menu-item-85)
- the menu item’s classes array does not already contain current_page_parent
If they’re all true, it adds the class current_page_parent to that menu item’s array of classes, so you can target it with your CSS.
The one downside to this approach is if you ever change your menu around, the menu item ID used in the function might change. I don’t know of any way around this, unfortunately – please let me know if you do!
As always, remember to add a unique prefix to your function names (like I’ve done with drollic) to avoid plugin/core conflicts.
Where does it go?
This adds a class that you’ll be styling from your theme CSS, so it belongs in your theme’s functions file. More thoughts on code location is in the first Function Friday post.
Resources
- Menu Item CSS Classes (on the page for the wp_nav_menu function) in the WordPress Code Reference
- nav_menu_css_class hook in the WordPress Code Reference
- is_singular function in the WordPress Code Reference
- is_tax function in the WordPress Code Reference
Leave a Reply