Here is my optimized/extended version of previously suggested solutions, which is pretty much fully automated. No more extra CSS or menu attributes needed.
This version dynamically gets a list of custom post types and if the current post type is a custom post type, then it removes the 'current_page_parent' class from all menu items.
Furthermore it checks each menu item to see if it's for a page with a page template like "page-{custom_post_type_slug}.php", and if so, it'll add the 'current_page_parent' class.
The filter priority is 1, as some themes, replace the current_page_parent/etc. classes with a class like 'active' (eg. 'roots' does this), so this filter needs to execute first.
Lastly, it makes use of 3 static variables since this function is repeatedly called and these (obviously) remain the same through all calls.
function theme_current_type_nav_class($css_class, $item) {
static $custom_post_types, $post_type, $filter_func;
if (empty($custom_post_types))
$custom_post_types = get_post_types(array('_builtin' => false));
if (empty($post_type))
$post_type = get_post_type();
if ('page' == $item->object && in_array($post_type, $custom_post_types)) {
$css_class = array_filter($css_class, function($el) {
return $el !== "current_page_parent";
});
$template = get_page_template_slug($item->object_id);
if (!empty($template) && preg_match("/^page(-[^-]+)*-$post_type/", $template) === 1)
array_push($css_class, 'current_page_parent');
}
return $css_class;
}
add_filter('nav_menu_css_class', 'theme_current_type_nav_class', 1, 2);
PS. Just to point out one shortcoming in all non-CSS solutions I've seen so far, including my own:
Something not taken into account is highlighting the menu item parent/ancestor of an item linking to a page which displays posts of the current custom post type. Consider a custom post type "product" and a menu like:
Home Company News Contact
|
\--About Us
\--Products
"Products" is a page with a template "page-product.php" and shows an overview of posts of type 'product'. It is highlighted due to posted solution. However 'Company' as its parent/ancestor should also be highlighted, but isn't. Something to keep in mind.