-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Navigation Block should support current-menu-item #19993
Comments
I was thinking of the exact same thing for a couple of weeks... Right now the nav block is nothing more than a styled links list. Wrote this today, didn't have time to test it yet but it's a start: add_filter( 'render_block_data', function( $block, $source ) {
// Early exit if innerBlocks doesn't exist.
if ( ! isset( $block['innerBlocks'] ) ) {
return $block;
}
foreach ( $block['innerBlocks'] as $key => $innerAttrs ) {
// Skip if we're not in a nav-link.
if ( 'core/navigation-link' !== $innerAttrs['blockName'] ) {
continue;
}
// Skip if ID is defined and not the same as the current page.
if ( isset( $innerAttrs['attrs']['id'] ) && get_the_ID() !== $innerAttrs['attrs']['id'] ) {
continue;
}
// Skip if URL is defined and not the same as the current URL.
if ( isset( $innerAttrs['attrs']['url'] ) && get_permalink() !== $innerAttrs['attrs']['url'] ) {
continue;
}
// If we got this far, we need to add the classname.
// First make sure it is defined.
if ( ! isset( $block['innerBlocks'][ $key ]['attrs']['className'] ) ) {
$block['innerBlocks'][ $key ]['attrs']['className'] = '';
}
// Add the classname.
$block['innerBlocks'][ $key ]['attrs']['className'] .= ' active';
}
return $block;
}, 10, 2 ); The logic is pretty simple:
I'll work on this a bit during the weekend, the above is just an idea (I don't even know if it works at this point). EDIT: The above code wasn't working because of a bug, see updated comment with code below. |
This solution is a bit hacky, but it works: add_filter( 'render_block_data', function( $block ) {
// Early exit if not a nav block.
if ( 'core/navigation' !== $block['blockName'] ) {
return $block;
}
foreach ( array_keys( $block['innerBlocks'] ) as $key ) {
// Skip if ID is defined and not the same as the current page.
if ( isset( $block['innerBlocks'][ $key ]['attrs']['id'] ) && get_the_ID() !== $block['innerBlocks'][ $key ]['attrs']['id'] ) {
continue;
}
// Skip if URL is defined and not the same as the current URL.
if ( isset( $block['innerBlocks'][ $key ]['attrs']['url'] ) && get_permalink() !== $block['innerBlocks'][ $key ]['attrs']['url'] ) {
continue;
}
// If we got this far, we need to add the classname.
// First make sure it is defined.
if ( ! isset( $block['innerBlocks'][ $key ]['attrs']['className'] ) ) {
$block['innerBlocks'][ $key ]['attrs']['className'] = '';
}
// Add the classname.
$block['innerBlocks'][ $key ]['attrs']['className'] = trim( $block['innerBlocks'][ $key ]['attrs']['className'] . ' active-nav-item' );
}
return $block;
} );
add_filter( 'render_block', function( $content, $block ) {
// Early exit if not a nav block.
if ( 'core/navigation' !== $block['blockName'] ) {
return $content;
}
// Check if we have an active item in this nav.
$active_item_url = false;
foreach ( $block['innerBlocks'] as $innerBlock ) {
if ( isset( $innerBlock['attrs']['className'] ) && false !== strpos($innerBlock['attrs']['className'], 'active-nav-item' ) ) {
$active_item_url = $innerBlock['attrs']['url'];
}
}
// Early exit if this nav doesn't have an active item.
if ( ! $active_item_url ) {
return $content;
}
// Add the "active-nav-item" class to the active item.
$parts = explode( 'wp-block-navigation-link"', $content );
foreach ( $parts as $part_key => $part ) {
$part = ( 0 === $part_key ) ? $part : '"' . $part;
if ( false !== strpos( $part, 'href="' . $active_item_url . '"' ) ) {
$part = ' active-nav-item' . $part;
}
$parts[ $part_key ] = $part;
}
return implode( 'wp-block-navigation-link', $parts );
}, 10, 2 ); The above code consists of 2 hooks:
|
Another solution via JS: add_action( 'wp_footer', function() {
?>
<script>
document.body.querySelectorAll( '.wp-block-navigation' ).forEach( function( navBlock ) {
navBlock.querySelectorAll( '[href="' + window.location.href + '"]' ).forEach( function( navActiveLink ) {
navActiveLink.parentNode.classList.add( 'active-nav-item' );
});
});
</script>
<?php
} ); This just adds a script in the footer of the site by hooking in Both this and the PHP solution posted above are imperfect, so only useful as workarounds until this gets fixed in the core block 👍 |
Just tested the PHP version and this works perfectly. I'll use this workaround until it is fixed in core. Thank you @aristath Not 100% sure of the etiquette here - should I close this issue now that there is a workaround? |
Hi @Bowriverstudio thank you for reporting this issue. @aristath thank you for researching this and providing a workaround. Hi @draganescu, @getdave, @retrofox, any thoughts on this? Is this something we should address before 5.4? |
I can test this and see if it raises any issues. If it is straightforward we could release this as well. |
Highlighting the currently active menu item is a common practice that helps sighted users understand where they are in a site, and also a best practice for a11y. |
Confirmed. Classes get added to menu items for posts/pages etc, and it looks like menu-item classes also get echoed. 👍 |
This has been rolled into core WordPress, but doesn't seem to work for the blog when the home page is set to a static page. i.e. If the blog itself is actually a page, the navigation menu doesn't get the current-menu-item class added to it. |
_I use Wordpress 6.4.2 for building a custom theme. Inserting core navigation block does not have any indication of current class. I have checked TwentyTwentyFour theme and UPD: Ok. It seems to me that I had to add my menu items to the existing pages. I did it before creating pages just writing the links, and probably, it was the issue. It would be nice if it worked this way to. I usually start building themes from header and footer and only after that add the pages. |
In Gutenberg 7.3 I've added the navigation block.
When I'm on the Current Page the navigation block does not add the css class "current-menu-item".
Describe alternatives you've considered
In my case I've got four pages. So I just created a navigation block for each page, and added custom css.
Thank you.
The text was updated successfully, but these errors were encountered: