HI @mcbmcb0 It should be possible to do that still with the wp_nav_menu_items filter. I’m not sure about the default menu – but if you are able to use the menu ID it should work with the method shown here:
https://developer.wordpress.org/reference/hooks/wp_nav_menu_items/
It really depends on what block is outputting the nav menu item. Assuming it’s the Navigation Link block, you could filter render_block_core/navigation-link.
Here’s the specific hook for filtering a specific block: https://developer.wordpress.org/reference/hooks/render_block_this-name/
But it’d help to know more precisely what you’re trying to accomplish to offer the best advice.
This will filter the navigation block in Twenty Twenty Four.
add_filter( 'render_block_core/navigation', 'wpsites_nav_menu_admins', 10, 2 );
function wpsites_nav_menu_admins( $block_content, $block ) {
if ( isset( $block['blockName'] ) && 'core/navigation' === $block['blockName'] ) {
if ( is_user_logged_in() && current_user_can( 'administrator' ) ) {
$custom_message = '<p class="admin-message">Welcome, Admin!</p>';
$block_content = $custom_message . $block_content;
}
}
return $block_content;
}
To target a specific menu item., use code like this :
add_filter( 'render_block_core/navigation', 'wpsites_modify_specific_menu_item_for_admins', 10, 2 );
function wpsites_modify_specific_menu_item_for_admins( $block_content, $block ) {
if ( isset( $block['blockName'] ) && 'core/navigation' === $block['blockName'] ) {
if ( is_user_logged_in() && current_user_can( 'administrator' ) ) {
$dom = new DOMDocument();
@$dom->loadHTML('<?xml encoding="utf-8" ?>' . $block_content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
$menu_items = $xpath->query('//a');
foreach ($menu_items as $menu_item) {
if ($menu_item->textContent === 'Product') {
$menu_item->setAttribute('class', 'admin-custom-class');
// $menu_item->setAttribute('href', 'https://example.com/admin-special');
}
}
$block_content = $dom->saveHTML();
}
}
return $block_content;
}
Hi
thanks for your suggestons. the goal is to hide a menu item for non-admins. As far as i can tell, i’ve duplicated and modified the standard nav menu under ‘patterns’.
unfortunately, the filters for wp_nav_menu_items and render_block_core/navigation-link don’t fire for me, but ‘render_block_core/navigation‘ does! i can catch the item with the code suggested by Brad (thanks!).
$menu_item->parentNode->removeChild($menu_item) would error, so I can hide it by
$menu_item->setAttribute('href', '');
$menu_item->textContent='';
which does leave some padding for the empty <a> , but its tolerable.
On a side note, i’m slightly shocked I have to crawl the DOM to find it, but it runs fast enough regardless.
thanks again!
even better – given we’re in the DOM, i add an item to the nav menu when the conditons are met (rather than removing one when they are now – more fail-safe:
$frag = $dom->createDocumentFragment();
$frag->appendXML( '<li class=" wp-block-navigation-item wp-block-navigation-link">
<a class="wp-block-navigation-item__content" href="https://wordpress.org/Admin-info/">
<span class="wp-block-navigation-item__label">Admin</span></a></li>');
$menu_item->parentNode->AppendChild( $frag ); // at then end