I have tested and confirmed the following works with a Nav block containing a Menu block and a standalone Menu block.
The code does two things:
- Makes nav/menu items highlight when they are logically hierarchical ancestors based on the URL
e.g. https://site.com/type will be highlighted if what is being currently viewed is a page or post with the url https://site.com/type/some-page-or-post - Makes nav/menu items highlight when they are hierarchically related by custom taxonomy
e.g. when a viewing a post, the taxonomy terms related to it will be highlighted.
This may require tweaking for some custom configurations but should cover most normal hierarchical scenarios.
Firstly, you will need to add the below custom code to your site:
function string_starts_with($haystack, $needle) {
return $haystack[0] === $needle[0] ? strncmp($haystack, $needle, strlen($needle)) === 0 : false;
}
function update_menu_item_classes( $classes, $item ) {
global $post;
$front_page_id = (int) get_option('page_on_front');
$item_id = (int) $item->object_id;
if (is_single() && ($item_id !== $front_page_id)) {
$post_url = get_permalink($post);
$post_type = $post->post_type;
if ($post_type == $item->object || string_starts_with($post_url, $item->url)) {
$classes[] = 'current-page-parent';
} else {
$post_taxonomies = get_object_taxonomies($post);
if (! empty($post_taxonomies)) {
foreach ($post_taxonomies as $matched_term_type) {
if ($matched_term_type != $item->object) {
continue;
}
$matched_terms = get_the_terms( $post, $matched_term_type );
$term_slug = '';
if( ! empty( $matched_terms ) ) {
foreach ( $matched_terms as $term ) {
$term_slug = $term->slug;
break;
}
}
$menu_item_term = ($matched_term_type != 'category') ? get_term($item->object_id) : get_category($item->object_id);
if ($term_slug && $menu_item_term->slug == $term_slug) {
$classes[] = 'current-menu-item';
break;
}
}
}
}
}
return $classes;
}
function highlight_custom_posts_taxonomy_menu_items( $items ) {
foreach ( $items as $key => $item ) {
$item->classes = update_menu_item_classes($item->classes, $item);
}
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'highlight_custom_posts_taxonomy_menu_items' );
For information on how to add custom code, please see the following tip:
Then add a global class to your Nav or Menu block (e.g. called nav).
Finally, add these relative styles to the global class as required.
For Menu:
For Nav:
You can add any styling you want to these relative styles, such as make the text bold or change the colour of the text, etc:
Note: currently this will not highlight a menu item that is a root relative custom link (e.g. “/some-folder/”) as WordPress posts have a full URL.