Printing navigation-block HTML from a legacy menu in themes

Full-Site Editing (or FSEFSE Short for Full Site Editing, a project for the Gutenberg plugin and the editor where a full page layout is created using only blocks. for short) is scheduled to be released with WordPress 5.6. In the meantime, the GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party includes a Navigation BlockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. that theme-authors can use to experiment and preview what their navigation will look like once users are able to use FSE on their sites.

You can already start preparing for this shift by making the default WordPress navigation use an HTMLHTML HTML is an acronym for Hyper Text Markup Language. It is a markup language that is used in the development of web pages and websites. structure similar to what the Navigation block is going to print.

To do that, you can paste the following code in your theme’s functions.php file:

/**
 * Filters the CSS class(es) applied to a menu list element.
 *
 * @param array $classes Array of the CSS classes that are applied to the menu `<ul>` element.
 * @return array
 */
add_filter( 'nav_menu_submenu_css_class', function( $classes ) {
    return [ 'wp-block-navigation__container' ];
} );

/**
 * Filters the CSS classes applied to a menu item's list item element.
 * 
 * @param array $classes Array of the CSS classes that are applied to the menu item's `<li>` element.
 * @return array
 */
add_filter( 'nav_menu_css_class', function( $classes ) {
    $item_classes = [ 'wp-block-navigation-link' ];
    if ( in_array( 'current-menu-item', $classes ) ) {
        $item_classes[] = 'current-menu-item';
    }
    if ( in_array( 'menu-item-has-children', $classes ) ) {
        $item_classes[] = 'has-child';
    }
    return $item_classes;
} );

/**
 * Filters the HTML attributes applied to a menu item's anchor element.
 * 
 * @param array $atts The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored.
 * @return array
 */
add_filter( 'nav_menu_link_attributes', function( $atts ) {
    $atts['class'] = 'wp-block-navigation-link__content';
    return $atts;
} );

/**
 * Filters a menu item's title.
 * 
 * @param string $title The menu item's title.
 * @return string
 */
add_filter( 'nav_menu_item_title', function( $title ) {
    return '<span class="wp-block-navigation-link__label">' . $title . '</span>';
} );

/**
 * Filters a menu item's starting output.
 * 
 * Append the dropdown arrow to links with submenus.
 * 
 * @param string   $item_output The menu item's starting HTML output.
 * @param WP_Post  $item        Menu item data object.
 * @return string
 */
add_filter( 'walker_nav_menu_start_el', function( $item_output, $item ) {
    $has_children = in_array( 'menu-item-has-children', $item->classes );
    if ( $has_children ) {
        $item_output = str_replace(
            '</a>',
            '</a><span class="wp-block-navigation-link__submenu-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" transform="rotate(90)"><path d="M8 5v14l11-7z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></span>',
            $item_output
        );
    }
    return $item_output;
}, 10, 2 );

Then to print the navigation you can use the following in your header.php file:

<nav class="wp-block-navigation" role="navigation">
	<ul class="wp-block-navigation__container">
		<?php
		wp_nav_menu(
			array(
				'container' => '',
				'items_wrap' => '%3$s',
				'theme_location' => 'primary',
			)
		);
		?>
	</ul>
</nav>

This will allow you to see what the future structure of navigation will be in WordPress themes and you can start converting your styles & scripts accordingly to accommodate these changes and be ready for when they land in WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress..