1

I did this all the time pre-full-site-editing, back when we all built menus under Appearance. But without the Menu option under Appearance anymore, how do I do this?

Is it only possible by way of a home-rolled function in functions.php or in javascript? I tried a function under add_filter( 'wp_nav_menu_items', 'delink_menu_item', 10, 2 ); but there were no $items or $args. Does FSE use a new function or filter? I could do this with jQuery, but not my favorite approach.

Thoughts?

2
  • I still have menu options under appearance. None the less just set the target of a top level to # and it won't link to anything.
    – rudtek
    Commented Feb 14, 2023 at 15:51
  • Unfortunately, you don't the Menu under Appearance in an FSE environment.
    – breadwild
    Commented Feb 14, 2023 at 19:30

2 Answers 2

5

The new FSE editor uses a new filter, if you want to hook into that you can do it in two ways:

By hooking the individual block rendering:

add_filter( 'render_block_core/navigation-link', 'test_render_navigation_link', 10, 3);

function test_render_navigation_link($block_content, $block) {
    $attributes = $block["attrs"];
    
    // string replace the href if you want, by checking the content of $attributes
    return $block_content;
}

or by hooking the prerender for the entire navigational menu:

add_filter( 'block_core_navigation_render_inner_blocks', 'replace_nav_blockitem_href');

function replace_nav_blockitem_href( $items ) {
    
    // Loop through the items (they are nested)
    foreach ($items as $key => $item) {
        //recursive loop through $item->inner_blocks
        //once you have found your item then set the attribute url to empty
        $item->parsed_block["attrs"]["url"] = null;
    }
    return $items;
}

The rendering of the navigation item will not output the href if the url is empty, this can be seen in the source code of the rendering: https://github.com/WordPress/wordpress-develop/blob/0cb8475c0d07d23893b1d73d755eda5f12024585/src/wp-includes/blocks/navigation-link.php#L173

This is the line where the first filter is called: https://github.com/WordPress/wordpress-develop/blob/28f10e4af559c9b4dbbd1768feff0bae575d5e78/src/wp-includes/class-wp-block.php#L306

This is the line where the second filter is called: https://github.com/WordPress/wordpress-develop/blob/0cb8475c0d07d23893b1d73d755eda5f12024585/src/wp-includes/blocks/navigation.php#L512

1
  • Ah, so a new filter. So helpful! Hopefully, this will make it into the docs eventually.
    – breadwild
    Commented Feb 15, 2023 at 15:25
1

In the end it was too easy to turn to jQuery. I saved it to a .js file, enqueued it, now good to go:

    var $j = jQuery.noConflict();
        
    $j(function() {
        //remove link from top-level menu items
        $j('ul.wp-block-page-list li.has-child > a').removeAttr('href');
    });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.