render_block_core_navigation

The timeline below displays how wordpress function render_block_core_navigation has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.5

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array    $attributes The block attributes.
 * @param string   $content    The saved content.
 * @param WP_Block $block      The parsed block.
 *
 * @return string Returns the navigation block markup.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    return WP_Navigation_Block_Renderer::render($attributes, $content, $block);
}

WordPress Version: 6.4

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array    $attributes The block attributes.
 * @param string   $content    The saved content.
 * @param WP_Block $block      The parsed block.
 *
 * @return string Returns the post content with the legacy widget added.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    static $seen_menu_names = array();
    // Flag used to indicate whether the rendered output is considered to be
    // a fallback (i.e. the block has no menu associated with it).
    $is_fallback = false;
    $nav_menu_name = $attributes['ariaLabel'] ?? '';
    /**
     * Deprecated:
     * The rgbTextColor and rgbBackgroundColor attributes
     * have been deprecated in favor of
     * customTextColor and customBackgroundColor ones.
     * Move the values from old attrs to the new ones.
     */
    if (isset($attributes['rgbTextColor']) && empty($attributes['textColor'])) {
        $attributes['customTextColor'] = $attributes['rgbTextColor'];
    }
    if (isset($attributes['rgbBackgroundColor']) && empty($attributes['backgroundColor'])) {
        $attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
    }
    unset($attributes['rgbTextColor'], $attributes['rgbBackgroundColor']);
    /**
     * This is for backwards compatibility after `isResponsive` attribute has been removed.
     */
    $has_old_responsive_attribute = !empty($attributes['isResponsive']) && $attributes['isResponsive'];
    $is_responsive_menu = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
    $inner_blocks = $block->inner_blocks;
    // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
    if (array_key_exists('navigationMenuId', $attributes)) {
        $attributes['ref'] = $attributes['navigationMenuId'];
    }
    // If:
    // - the gutenberg plugin is active
    // - `__unstableLocation` is defined
    // - we have menu items at the defined location
    // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
    // ...then create inner blocks from the classic menu assigned to that location.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && array_key_exists('__unstableLocation', $attributes) && !array_key_exists('ref', $attributes) && !empty(block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']))) {
        $menu_items = block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']);
        if (empty($menu_items)) {
            return '';
        }
        $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id($menu_items);
        $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items($menu_items_by_parent_id[0], $menu_items_by_parent_id);
        $inner_blocks = new WP_Block_List($parsed_blocks, $attributes);
    }
    // Load inner blocks from the navigation post.
    if (array_key_exists('ref', $attributes)) {
        $navigation_post = get_post($attributes['ref']);
        if (!isset($navigation_post)) {
            return '';
        }
        // Only published posts are valid. If this is changed then a corresponding change
        // must also be implemented in `use-navigation-menu.js`.
        if ('publish' === $navigation_post->post_status) {
            $nav_menu_name = $navigation_post->post_title;
            if (isset($seen_menu_names[$nav_menu_name])) {
                ++$seen_menu_names[$nav_menu_name];
            } else {
                $seen_menu_names[$nav_menu_name] = 1;
            }
            $parsed_blocks = parse_blocks($navigation_post->post_content);
            // 'parse_blocks' includes a null block with '\n\n' as the content when
            // it encounters whitespace. This code strips it.
            $compacted_blocks = block_core_navigation_filter_out_empty_blocks($parsed_blocks);
            // TODO - this uses the full navigation block attributes for the
            // context which could be refined.
            $inner_blocks = new WP_Block_List($compacted_blocks, $attributes);
        }
    }
    // If there are no inner blocks then fallback to rendering an appropriate fallback.
    if (empty($inner_blocks)) {
        $is_fallback = true;
        // indicate we are rendering the fallback.
        $fallback_blocks = block_core_navigation_get_fallback_blocks();
        // Fallback my have been filtered so do basic test for validity.
        if (empty($fallback_blocks) || !is_array($fallback_blocks)) {
            return '';
        }
        $inner_blocks = new WP_Block_List($fallback_blocks, $attributes);
    }
    if (block_core_navigation_block_contains_core_navigation($inner_blocks)) {
        return '';
    }
    /**
     * Filter navigation block $inner_blocks.
     * Allows modification of a navigation block menu items.
     *
     * @since 6.1.0
     *
     * @param \WP_Block_List $inner_blocks
     */
    $inner_blocks = apply_filters('block_core_navigation_render_inner_blocks', $inner_blocks);
    $layout_justification = array('left' => 'items-justified-left', 'right' => 'items-justified-right', 'center' => 'items-justified-center', 'space-between' => 'items-justified-space-between');
    // Restore legacy classnames for submenu positioning.
    $layout_class = '';
    if (isset($attributes['layout']['justifyContent']) && isset($layout_justification[$attributes['layout']['justifyContent']])) {
        $layout_class .= $layout_justification[$attributes['layout']['justifyContent']];
    }
    if (isset($attributes['layout']['orientation']) && 'vertical' === $attributes['layout']['orientation']) {
        $layout_class .= ' is-vertical';
    }
    if (isset($attributes['layout']['flexWrap']) && 'nowrap' === $attributes['layout']['flexWrap']) {
        $layout_class .= ' no-wrap';
    }
    // Manually add block support text decoration as CSS class.
    $text_decoration = $attributes['style']['typography']['textDecoration'] ?? null;
    $text_decoration_class = sprintf('has-text-decoration-%s', $text_decoration);
    $colors = block_core_navigation_build_css_colors($attributes);
    $font_sizes = block_core_navigation_build_css_font_sizes($attributes);
    $classes = array_merge($colors['css_classes'], $font_sizes['css_classes'], $is_responsive_menu ? array('is-responsive') : array(), $layout_class ? array($layout_class) : array(), $is_fallback ? array('is-fallback') : array(), $text_decoration ? array($text_decoration_class) : array());
    $post_ids = block_core_navigation_get_post_ids($inner_blocks);
    if ($post_ids) {
        _prime_post_caches($post_ids, false, false);
    }
    $list_item_nav_blocks = array('core/navigation-link', 'core/home-link', 'core/site-title', 'core/site-logo', 'core/navigation-submenu');
    $needs_list_item_wrapper = array('core/site-title', 'core/site-logo');
    $block_styles = isset($attributes['styles']) ? $attributes['styles'] : '';
    $style = $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'];
    $class = implode(' ', $classes);
    // If the menu name has been used previously then append an ID
    // to the name to ensure uniqueness across a given post.
    if (isset($seen_menu_names[$nav_menu_name]) && $seen_menu_names[$nav_menu_name] > 1) {
        $count = $seen_menu_names[$nav_menu_name];
        $nav_menu_name = $nav_menu_name . ' ' . $count;
    }
    $wrapper_attributes = get_block_wrapper_attributes(array('class' => $class, 'style' => $style, 'aria-label' => $nav_menu_name));
    $container_attributes = get_block_wrapper_attributes(array('class' => 'wp-block-navigation__container ' . $class, 'style' => $style));
    $inner_blocks_html = '';
    $is_list_open = false;
    $has_submenus = false;
    foreach ($inner_blocks as $inner_block) {
        $is_list_item = in_array($inner_block->name, $list_item_nav_blocks, true);
        if ($is_list_item && !$is_list_open) {
            $is_list_open = true;
            $inner_blocks_html .= sprintf('<ul %1$s>', $container_attributes);
        }
        if (!$is_list_item && $is_list_open) {
            $is_list_open = false;
            $inner_blocks_html .= '</ul>';
        }
        $inner_block_content = $inner_block->render();
        $p = new WP_HTML_Tag_Processor($inner_block_content);
        if ($p->next_tag(array('name' => 'LI', 'class_name' => 'has-child'))) {
            $has_submenus = true;
        }
        if (!empty($inner_block_content)) {
            if (in_array($inner_block->name, $needs_list_item_wrapper, true)) {
                $inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block_content . '</li>';
            } else {
                $inner_blocks_html .= $inner_block_content;
            }
        }
    }
    if ($is_list_open) {
        $inner_blocks_html .= '</ul>';
    }
    $should_load_view_script = $has_submenus && ($attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon']) || $is_responsive_menu;
    $view_js_file = 'wp-block-navigation-view';
    // If the script already exists, there is no point in removing it from viewScript.
    if (!wp_script_is($view_js_file)) {
        $script_handles = $block->block_type->view_script_handles;
        // If the script is not needed, and it is still in the `view_script_handles`, remove it.
        if (!$should_load_view_script && in_array($view_js_file, $script_handles, true)) {
            $block->block_type->view_script_handles = array_diff($script_handles, array($view_js_file));
        }
        // If the script is needed, but it was previously removed, add it again.
        if ($should_load_view_script && !in_array($view_js_file, $script_handles, true)) {
            $block->block_type->view_script_handles = array_merge($script_handles, array($view_js_file));
        }
    }
    // Add directives to the submenu if needed.
    if ($has_submenus && $should_load_view_script) {
        $w = new WP_HTML_Tag_Processor($inner_blocks_html);
        $inner_blocks_html = block_core_navigation_add_directives_to_submenu($w, $attributes);
    }
    $modal_unique_id = wp_unique_id('modal-');
    // Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
    // return early if they don't.
    if (!$is_responsive_menu) {
        return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $inner_blocks_html);
    }
    $is_hidden_by_default = isset($attributes['overlayMenu']) && 'always' === $attributes['overlayMenu'];
    $responsive_container_classes = array('wp-block-navigation__responsive-container', $is_hidden_by_default ? 'hidden-by-default' : '', implode(' ', $colors['overlay_css_classes']));
    $open_button_classes = array('wp-block-navigation__responsive-container-open', $is_hidden_by_default ? 'always-shown' : '');
    $should_display_icon_label = isset($attributes['hasIcon']) && true === $attributes['hasIcon'];
    $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg>';
    if (isset($attributes['icon'])) {
        if ('menu' === $attributes['icon']) {
            $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 5v1.5h14V5H5zm0 7.8h14v-1.5H5v1.5zM5 19h14v-1.5H5V19z" /></svg>';
        }
    }
    $toggle_button_content = $should_display_icon_label ? $toggle_button_icon : __('Menu');
    $toggle_close_button_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg>';
    $toggle_close_button_content = $should_display_icon_label ? $toggle_close_button_icon : __('Close');
    $toggle_aria_label_open = $should_display_icon_label ? 'aria-label="' . __('Open menu') . '"' : '';
    // Open button label.
    $toggle_aria_label_close = $should_display_icon_label ? 'aria-label="' . __('Close menu') . '"' : '';
    // Close button label.
    // Add Interactivity API directives to the markup if needed.
    $nav_element_directives = '';
    $open_button_directives = '';
    $responsive_container_directives = '';
    $responsive_dialog_directives = '';
    $close_button_directives = '';
    if ($should_load_view_script) {
        $nav_element_context = wp_json_encode(array('core' => array('navigation' => array('overlayOpenedBy' => array(), 'type' => 'overlay', 'roleAttribute' => '', 'ariaLabel' => __('Menu')))), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP);
        $nav_element_directives = '
			data-wp-interactive
			data-wp-context=\'' . $nav_element_context . '\'
		';
        $open_button_directives = '
			data-wp-on--click="actions.core.navigation.openMenuOnClick"
			data-wp-on--keydown="actions.core.navigation.handleMenuKeydown"
		';
        $responsive_container_directives = '
			data-wp-class--has-modal-open="selectors.core.navigation.isMenuOpen"
			data-wp-class--is-menu-open="selectors.core.navigation.isMenuOpen"
			data-wp-effect="effects.core.navigation.initMenu"
			data-wp-on--keydown="actions.core.navigation.handleMenuKeydown"
			data-wp-on--focusout="actions.core.navigation.handleMenuFocusout"
			tabindex="-1"
		';
        $responsive_dialog_directives = '
			data-wp-bind--aria-modal="selectors.core.navigation.ariaModal"
			data-wp-bind--aria-label="selectors.core.navigation.ariaLabel"
			data-wp-bind--role="selectors.core.navigation.roleAttribute"
			data-wp-effect="effects.core.navigation.focusFirstElement"
		';
        $close_button_directives = '
			data-wp-on--click="actions.core.navigation.closeMenuOnClick"
		';
    }
    $responsive_container_markup = sprintf('<button aria-haspopup="true" %3$s class="%6$s" %10$s>%8$s</button>
			<div class="%5$s" style="%7$s" id="%1$s" %11$s>
				<div class="wp-block-navigation__responsive-close" tabindex="-1">
					<div class="wp-block-navigation__responsive-dialog" %12$s>
							<button %4$s class="wp-block-navigation__responsive-container-close" %13$s>%9$s</button>
						<div class="wp-block-navigation__responsive-container-content" id="%1$s-content">
							%2$s
						</div>
					</div>
				</div>
			</div>', esc_attr($modal_unique_id), $inner_blocks_html, $toggle_aria_label_open, $toggle_aria_label_close, esc_attr(implode(' ', $responsive_container_classes)), esc_attr(implode(' ', $open_button_classes)), esc_attr(safecss_filter_attr($colors['overlay_inline_styles'])), $toggle_button_content, $toggle_close_button_content, $open_button_directives, $responsive_container_directives, $responsive_dialog_directives, $close_button_directives);
    return sprintf('<nav %1$s %3$s>%2$s</nav>', $wrapper_attributes, $responsive_container_markup, $nav_element_directives);
}

WordPress Version: 6.3

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array    $attributes The block attributes.
 * @param string   $content    The saved content.
 * @param WP_Block $block      The parsed block.
 *
 * @return string Returns the post content with the legacy widget added.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    static $seen_menu_names = array();
    // Flag used to indicate whether the rendered output is considered to be
    // a fallback (i.e. the block has no menu associated with it).
    $is_fallback = false;
    $nav_menu_name = '';
    /**
     * Deprecated:
     * The rgbTextColor and rgbBackgroundColor attributes
     * have been deprecated in favor of
     * customTextColor and customBackgroundColor ones.
     * Move the values from old attrs to the new ones.
     */
    if (isset($attributes['rgbTextColor']) && empty($attributes['textColor'])) {
        $attributes['customTextColor'] = $attributes['rgbTextColor'];
    }
    if (isset($attributes['rgbBackgroundColor']) && empty($attributes['backgroundColor'])) {
        $attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
    }
    unset($attributes['rgbTextColor'], $attributes['rgbBackgroundColor']);
    /**
     * This is for backwards compatibility after `isResponsive` attribute has been removed.
     */
    $has_old_responsive_attribute = !empty($attributes['isResponsive']) && $attributes['isResponsive'];
    $is_responsive_menu = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
    $inner_blocks = $block->inner_blocks;
    // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
    if (array_key_exists('navigationMenuId', $attributes)) {
        $attributes['ref'] = $attributes['navigationMenuId'];
    }
    // If:
    // - the gutenberg plugin is active
    // - `__unstableLocation` is defined
    // - we have menu items at the defined location
    // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
    // ...then create inner blocks from the classic menu assigned to that location.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && array_key_exists('__unstableLocation', $attributes) && !array_key_exists('ref', $attributes) && !empty(block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']))) {
        $menu_items = block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']);
        if (empty($menu_items)) {
            return '';
        }
        $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id($menu_items);
        $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items($menu_items_by_parent_id[0], $menu_items_by_parent_id);
        $inner_blocks = new WP_Block_List($parsed_blocks, $attributes);
    }
    // Load inner blocks from the navigation post.
    if (array_key_exists('ref', $attributes)) {
        $navigation_post = get_post($attributes['ref']);
        if (!isset($navigation_post)) {
            return '';
        }
        // Only published posts are valid. If this is changed then a corresponding change
        // must also be implemented in `use-navigation-menu.js`.
        if ('publish' === $navigation_post->post_status) {
            $nav_menu_name = $navigation_post->post_title;
            if (isset($seen_menu_names[$nav_menu_name])) {
                ++$seen_menu_names[$nav_menu_name];
            } else {
                $seen_menu_names[$nav_menu_name] = 1;
            }
            $parsed_blocks = parse_blocks($navigation_post->post_content);
            // 'parse_blocks' includes a null block with '\n\n' as the content when
            // it encounters whitespace. This code strips it.
            $compacted_blocks = block_core_navigation_filter_out_empty_blocks($parsed_blocks);
            // TODO - this uses the full navigation block attributes for the
            // context which could be refined.
            $inner_blocks = new WP_Block_List($compacted_blocks, $attributes);
        }
    }
    // If there are no inner blocks then fallback to rendering an appropriate fallback.
    if (empty($inner_blocks)) {
        $is_fallback = true;
        // indicate we are rendering the fallback.
        $fallback_blocks = block_core_navigation_get_fallback_blocks();
        // Fallback my have been filtered so do basic test for validity.
        if (empty($fallback_blocks) || !is_array($fallback_blocks)) {
            return '';
        }
        $inner_blocks = new WP_Block_List($fallback_blocks, $attributes);
    }
    if (block_core_navigation_block_contains_core_navigation($inner_blocks)) {
        return '';
    }
    /**
     * Filter navigation block $inner_blocks.
     * Allows modification of a navigation block menu items.
     *
     * @since 6.1.0
     *
     * @param \WP_Block_List $inner_blocks
     */
    $inner_blocks = apply_filters('block_core_navigation_render_inner_blocks', $inner_blocks);
    $layout_justification = array('left' => 'items-justified-left', 'right' => 'items-justified-right', 'center' => 'items-justified-center', 'space-between' => 'items-justified-space-between');
    // Restore legacy classnames for submenu positioning.
    $layout_class = '';
    if (isset($attributes['layout']['justifyContent']) && isset($layout_justification[$attributes['layout']['justifyContent']])) {
        $layout_class .= $layout_justification[$attributes['layout']['justifyContent']];
    }
    if (isset($attributes['layout']['orientation']) && 'vertical' === $attributes['layout']['orientation']) {
        $layout_class .= ' is-vertical';
    }
    if (isset($attributes['layout']['flexWrap']) && 'nowrap' === $attributes['layout']['flexWrap']) {
        $layout_class .= ' no-wrap';
    }
    // Manually add block support text decoration as CSS class.
    $text_decoration = _wp_array_get($attributes, array('style', 'typography', 'textDecoration'), null);
    $text_decoration_class = sprintf('has-text-decoration-%s', $text_decoration);
    $colors = block_core_navigation_build_css_colors($attributes);
    $font_sizes = block_core_navigation_build_css_font_sizes($attributes);
    $classes = array_merge($colors['css_classes'], $font_sizes['css_classes'], $is_responsive_menu ? array('is-responsive') : array(), $layout_class ? array($layout_class) : array(), $is_fallback ? array('is-fallback') : array(), $text_decoration ? array($text_decoration_class) : array());
    $post_ids = block_core_navigation_get_post_ids($inner_blocks);
    if ($post_ids) {
        _prime_post_caches($post_ids, false, false);
    }
    $list_item_nav_blocks = array('core/navigation-link', 'core/home-link', 'core/site-title', 'core/site-logo', 'core/navigation-submenu');
    $needs_list_item_wrapper = array('core/site-title', 'core/site-logo');
    $block_styles = isset($attributes['styles']) ? $attributes['styles'] : '';
    $style = $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'];
    $class = implode(' ', $classes);
    // If the menu name has been used previously then append an ID
    // to the name to ensure uniqueness across a given post.
    if (isset($seen_menu_names[$nav_menu_name]) && $seen_menu_names[$nav_menu_name] > 1) {
        $count = $seen_menu_names[$nav_menu_name];
        $nav_menu_name = $nav_menu_name . ' ' . $count;
    }
    $wrapper_attributes = get_block_wrapper_attributes(array('class' => $class, 'style' => $style, 'aria-label' => $nav_menu_name));
    $container_attributes = get_block_wrapper_attributes(array('class' => 'wp-block-navigation__container ' . $class, 'style' => $style));
    $inner_blocks_html = '';
    $is_list_open = false;
    $has_submenus = false;
    foreach ($inner_blocks as $inner_block) {
        $is_list_item = in_array($inner_block->name, $list_item_nav_blocks, true);
        if ($is_list_item && !$is_list_open) {
            $is_list_open = true;
            $inner_blocks_html .= sprintf('<ul %1$s>', $container_attributes);
        }
        if (!$is_list_item && $is_list_open) {
            $is_list_open = false;
            $inner_blocks_html .= '</ul>';
        }
        $inner_block_content = $inner_block->render();
        $p = new WP_HTML_Tag_Processor($inner_block_content);
        if ($p->next_tag(array('name' => 'LI', 'class_name' => 'has-child'))) {
            $has_submenus = true;
        }
        if (!empty($inner_block_content)) {
            if (in_array($inner_block->name, $needs_list_item_wrapper, true)) {
                $inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block_content . '</li>';
            } else {
                $inner_blocks_html .= $inner_block_content;
            }
        }
    }
    if ($is_list_open) {
        $inner_blocks_html .= '</ul>';
    }
    // If the script already exists, there is no point in removing it from viewScript.
    $should_load_view_script = $is_responsive_menu || $has_submenus && ($attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon']);
    $view_js_file = 'wp-block-navigation-view';
    if (!wp_script_is($view_js_file)) {
        $script_handles = $block->block_type->view_script_handles;
        // If the script is not needed, and it is still in the `view_script_handles`, remove it.
        if (!$should_load_view_script && in_array($view_js_file, $script_handles, true)) {
            $block->block_type->view_script_handles = array_diff($script_handles, array($view_js_file, 'wp-block-navigation-view-2'));
        }
        // If the script is needed, but it was previously removed, add it again.
        if ($should_load_view_script && !in_array($view_js_file, $script_handles, true)) {
            $block->block_type->view_script_handles = array_merge($script_handles, array($view_js_file, 'wp-block-navigation-view-2'));
        }
    }
    // Add directives to the submenu if needed.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && $has_submenus && $should_load_view_script) {
        $w = new WP_HTML_Tag_Processor($inner_blocks_html);
        $inner_blocks_html = block_core_navigation_add_directives_to_submenu($w, $attributes);
    }
    $modal_unique_id = wp_unique_id('modal-');
    // Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
    // return early if they don't.
    if (!$is_responsive_menu) {
        return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $inner_blocks_html);
    }
    $is_hidden_by_default = isset($attributes['overlayMenu']) && 'always' === $attributes['overlayMenu'];
    $responsive_container_classes = array('wp-block-navigation__responsive-container', $is_hidden_by_default ? 'hidden-by-default' : '', implode(' ', $colors['overlay_css_classes']));
    $open_button_classes = array('wp-block-navigation__responsive-container-open', $is_hidden_by_default ? 'always-shown' : '');
    $should_display_icon_label = isset($attributes['hasIcon']) && true === $attributes['hasIcon'];
    $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg>';
    if (isset($attributes['icon'])) {
        if ('menu' === $attributes['icon']) {
            $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 5v1.5h14V5H5zm0 7.8h14v-1.5H5v1.5zM5 19h14v-1.5H5V19z" /></svg>';
        }
    }
    $toggle_button_content = $should_display_icon_label ? $toggle_button_icon : __('Menu');
    $toggle_close_button_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg>';
    $toggle_close_button_content = $should_display_icon_label ? $toggle_close_button_icon : __('Close');
    $toggle_aria_label_open = $should_display_icon_label ? 'aria-label="' . __('Open menu') . '"' : '';
    // Open button label.
    $toggle_aria_label_close = $should_display_icon_label ? 'aria-label="' . __('Close menu') . '"' : '';
    // Close button label.
    // Add Interactivity API directives to the markup if needed.
    $nav_element_directives = '';
    $open_button_directives = '';
    $responsive_container_directives = '';
    $responsive_dialog_directives = '';
    $close_button_directives = '';
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && $should_load_view_script) {
        $nav_element_directives = '
			data-wp-interactive
			data-wp-context=\'{ "core": { "navigation": { "isMenuOpen": { "click": false, "hover": false }, "overlay": true, "roleAttribute": "" } } }\'
		';
        $open_button_directives = '
			data-wp-on--click="actions.core.navigation.openMenuOnClick"
			data-wp-on--keydown="actions.core.navigation.handleMenuKeydown"
		';
        $responsive_container_directives = '
			data-wp-class--has-modal-open="selectors.core.navigation.isMenuOpen"
			data-wp-class--is-menu-open="selectors.core.navigation.isMenuOpen"
			data-wp-effect="effects.core.navigation.initMenu"
			data-wp-on--keydown="actions.core.navigation.handleMenuKeydown"
			data-wp-on--focusout="actions.core.navigation.handleMenuFocusout"
			tabindex="-1"
		';
        $responsive_dialog_directives = '
			data-wp-bind--aria-modal="selectors.core.navigation.isMenuOpen"
			data-wp-bind--role="selectors.core.navigation.roleAttribute"
			data-wp-effect="effects.core.navigation.focusFirstElement"
		';
        $close_button_directives = '
			data-wp-on--click="actions.core.navigation.closeMenuOnClick"
		';
    }
    $responsive_container_markup = sprintf('<button aria-haspopup="true" %3$s class="%6$s" data-micromodal-trigger="%1$s" %11$s>%9$s</button>
			<div class="%5$s" style="%7$s" id="%1$s" %12$s>
				<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
					<div class="wp-block-navigation__responsive-dialog" aria-label="%8$s" %13$s>
							<button %4$s data-micromodal-close class="wp-block-navigation__responsive-container-close" %14$s>%10$s</button>
						<div class="wp-block-navigation__responsive-container-content" id="%1$s-content">
							%2$s
						</div>
					</div>
				</div>
			</div>', esc_attr($modal_unique_id), $inner_blocks_html, $toggle_aria_label_open, $toggle_aria_label_close, esc_attr(implode(' ', $responsive_container_classes)), esc_attr(implode(' ', $open_button_classes)), esc_attr(safecss_filter_attr($colors['overlay_inline_styles'])), __('Menu'), $toggle_button_content, $toggle_close_button_content, $open_button_directives, $responsive_container_directives, $responsive_dialog_directives, $close_button_directives);
    return sprintf('<nav %1$s %3$s>%2$s</nav>', $wrapper_attributes, $responsive_container_markup, $nav_element_directives);
}

WordPress Version: 6.2

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array    $attributes The block attributes.
 * @param string   $content    The saved content.
 * @param WP_Block $block      The parsed block.
 *
 * @return string Returns the post content with the legacy widget added.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    static $seen_menu_names = array();
    // Flag used to indicate whether the rendered output is considered to be
    // a fallback (i.e. the block has no menu associated with it).
    $is_fallback = false;
    $nav_menu_name = '';
    /**
     * Deprecated:
     * The rgbTextColor and rgbBackgroundColor attributes
     * have been deprecated in favor of
     * customTextColor and customBackgroundColor ones.
     * Move the values from old attrs to the new ones.
     */
    if (isset($attributes['rgbTextColor']) && empty($attributes['textColor'])) {
        $attributes['customTextColor'] = $attributes['rgbTextColor'];
    }
    if (isset($attributes['rgbBackgroundColor']) && empty($attributes['backgroundColor'])) {
        $attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
    }
    unset($attributes['rgbTextColor'], $attributes['rgbBackgroundColor']);
    /**
     * This is for backwards compatibility after `isResponsive` attribute has been removed.
     */
    $has_old_responsive_attribute = !empty($attributes['isResponsive']) && $attributes['isResponsive'];
    $is_responsive_menu = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
    $should_load_view_script = !wp_script_is('wp-block-navigation-view') && ($is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon']);
    if ($should_load_view_script) {
        wp_enqueue_script('wp-block-navigation-view');
    }
    $should_load_modal_view_script = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'];
    if ($should_load_modal_view_script) {
        wp_enqueue_script('wp-block-navigation-view-modal');
    }
    $inner_blocks = $block->inner_blocks;
    // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
    if (array_key_exists('navigationMenuId', $attributes)) {
        $attributes['ref'] = $attributes['navigationMenuId'];
    }
    // If:
    // - the gutenberg plugin is active
    // - `__unstableLocation` is defined
    // - we have menu items at the defined location
    // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
    // ...then create inner blocks from the classic menu assigned to that location.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && array_key_exists('__unstableLocation', $attributes) && !array_key_exists('ref', $attributes) && !empty(block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']))) {
        $menu_items = block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']);
        if (empty($menu_items)) {
            return '';
        }
        $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id($menu_items);
        $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items($menu_items_by_parent_id[0], $menu_items_by_parent_id);
        $inner_blocks = new WP_Block_List($parsed_blocks, $attributes);
    }
    // Load inner blocks from the navigation post.
    if (array_key_exists('ref', $attributes)) {
        $navigation_post = get_post($attributes['ref']);
        if (!isset($navigation_post)) {
            return '';
        }
        // Only published posts are valid. If this is changed then a corresponding change
        // must also be implemented in `use-navigation-menu.js`.
        if ('publish' === $navigation_post->post_status) {
            $nav_menu_name = $navigation_post->post_title;
            if (isset($seen_menu_names[$nav_menu_name])) {
                ++$seen_menu_names[$nav_menu_name];
            } else {
                $seen_menu_names[$nav_menu_name] = 1;
            }
            $parsed_blocks = parse_blocks($navigation_post->post_content);
            // 'parse_blocks' includes a null block with '\n\n' as the content when
            // it encounters whitespace. This code strips it.
            $compacted_blocks = block_core_navigation_filter_out_empty_blocks($parsed_blocks);
            // TODO - this uses the full navigation block attributes for the
            // context which could be refined.
            $inner_blocks = new WP_Block_List($compacted_blocks, $attributes);
        }
    }
    // If there are no inner blocks then fallback to rendering an appropriate fallback.
    if (empty($inner_blocks)) {
        $is_fallback = true;
        // indicate we are rendering the fallback.
        $fallback_blocks = block_core_navigation_get_fallback_blocks();
        // Fallback my have been filtered so do basic test for validity.
        if (empty($fallback_blocks) || !is_array($fallback_blocks)) {
            return '';
        }
        $inner_blocks = new WP_Block_List($fallback_blocks, $attributes);
    }
    if (block_core_navigation_block_contains_core_navigation($inner_blocks)) {
        return '';
    }
    /**
     * Filter navigation block $inner_blocks.
     * Allows modification of a navigation block menu items.
     *
     * @since 6.1.0
     *
     * @param \WP_Block_List $inner_blocks
     */
    $inner_blocks = apply_filters('block_core_navigation_render_inner_blocks', $inner_blocks);
    $layout_justification = array('left' => 'items-justified-left', 'right' => 'items-justified-right', 'center' => 'items-justified-center', 'space-between' => 'items-justified-space-between');
    // Restore legacy classnames for submenu positioning.
    $layout_class = '';
    if (isset($attributes['layout']['justifyContent'])) {
        $layout_class .= $layout_justification[$attributes['layout']['justifyContent']];
    }
    if (isset($attributes['layout']['orientation']) && 'vertical' === $attributes['layout']['orientation']) {
        $layout_class .= ' is-vertical';
    }
    if (isset($attributes['layout']['flexWrap']) && 'nowrap' === $attributes['layout']['flexWrap']) {
        $layout_class .= ' no-wrap';
    }
    // Manually add block support text decoration as CSS class.
    $text_decoration = _wp_array_get($attributes, array('style', 'typography', 'textDecoration'), null);
    $text_decoration_class = sprintf('has-text-decoration-%s', $text_decoration);
    $colors = block_core_navigation_build_css_colors($attributes);
    $font_sizes = block_core_navigation_build_css_font_sizes($attributes);
    $classes = array_merge($colors['css_classes'], $font_sizes['css_classes'], $is_responsive_menu ? array('is-responsive') : array(), $layout_class ? array($layout_class) : array(), $is_fallback ? array('is-fallback') : array(), $text_decoration ? array($text_decoration_class) : array());
    $post_ids = block_core_navigation_get_post_ids($inner_blocks);
    if ($post_ids) {
        _prime_post_caches($post_ids, false, false);
    }
    $list_item_nav_blocks = array('core/navigation-link', 'core/home-link', 'core/site-title', 'core/site-logo', 'core/navigation-submenu');
    $needs_list_item_wrapper = array('core/site-title', 'core/site-logo');
    $inner_blocks_html = '';
    $is_list_open = false;
    foreach ($inner_blocks as $inner_block) {
        $is_list_item = in_array($inner_block->name, $list_item_nav_blocks, true);
        if ($is_list_item && !$is_list_open) {
            $is_list_open = true;
            $inner_blocks_html .= '<ul class="wp-block-navigation__container">';
        }
        if (!$is_list_item && $is_list_open) {
            $is_list_open = false;
            $inner_blocks_html .= '</ul>';
        }
        $inner_block_content = $inner_block->render();
        if (!empty($inner_block_content)) {
            if (in_array($inner_block->name, $needs_list_item_wrapper, true)) {
                $inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block_content . '</li>';
            } else {
                $inner_blocks_html .= $inner_block_content;
            }
        }
    }
    if ($is_list_open) {
        $inner_blocks_html .= '</ul>';
    }
    $block_styles = isset($attributes['styles']) ? $attributes['styles'] : '';
    // If the menu name has been used previously then append an ID
    // to the name to ensure uniqueness across a given post.
    if (isset($seen_menu_names[$nav_menu_name]) && $seen_menu_names[$nav_menu_name] > 1) {
        $count = $seen_menu_names[$nav_menu_name];
        $nav_menu_name = $nav_menu_name . ' ' . $count;
    }
    $wrapper_attributes = get_block_wrapper_attributes(array('class' => implode(' ', $classes), 'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'], 'aria-label' => $nav_menu_name));
    $modal_unique_id = wp_unique_id('modal-');
    // Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
    // return early if they don't.
    if (!$is_responsive_menu) {
        return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $inner_blocks_html);
    }
    $is_hidden_by_default = isset($attributes['overlayMenu']) && 'always' === $attributes['overlayMenu'];
    $responsive_container_classes = array('wp-block-navigation__responsive-container', $is_hidden_by_default ? 'hidden-by-default' : '', implode(' ', $colors['overlay_css_classes']));
    $open_button_classes = array('wp-block-navigation__responsive-container-open', $is_hidden_by_default ? 'always-shown' : '');
    $should_display_icon_label = isset($attributes['hasIcon']) && true === $attributes['hasIcon'];
    $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg>';
    if (isset($attributes['icon'])) {
        if ('menu' === $attributes['icon']) {
            $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 5v1.5h14V5H5zm0 7.8h14v-1.5H5v1.5zM5 19h14v-1.5H5V19z" /></svg>';
        }
    }
    $toggle_button_content = $should_display_icon_label ? $toggle_button_icon : __('Menu');
    $toggle_close_button_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg>';
    $toggle_close_button_content = $should_display_icon_label ? $toggle_close_button_icon : __('Close');
    $toggle_aria_label_open = $should_display_icon_label ? 'aria-label="' . __('Open menu') . '"' : '';
    // Open button label.
    $toggle_aria_label_close = $should_display_icon_label ? 'aria-label="' . __('Close menu') . '"' : '';
    // Close button label.
    $responsive_container_markup = sprintf('<button aria-haspopup="true" %3$s class="%6$s" data-micromodal-trigger="%1$s">%9$s</button>
			<div class="%5$s" style="%7$s" id="%1$s">
				<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
					<div class="wp-block-navigation__responsive-dialog" aria-label="%8$s">
							<button %4$s data-micromodal-close class="wp-block-navigation__responsive-container-close">%10$s</button>
						<div class="wp-block-navigation__responsive-container-content" id="%1$s-content">
							%2$s
						</div>
					</div>
				</div>
			</div>', esc_attr($modal_unique_id), $inner_blocks_html, $toggle_aria_label_open, $toggle_aria_label_close, esc_attr(implode(' ', $responsive_container_classes)), esc_attr(implode(' ', $open_button_classes)), esc_attr(safecss_filter_attr($colors['overlay_inline_styles'])), __('Menu'), $toggle_button_content, $toggle_close_button_content);
    return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $responsive_container_markup);
}

WordPress Version: 6.1

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array    $attributes The block attributes.
 * @param string   $content    The saved content.
 * @param WP_Block $block      The parsed block.
 *
 * @return string Returns the post content with the legacy widget added.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    static $seen_menu_names = array();
    // Flag used to indicate whether the rendered output is considered to be
    // a fallback (i.e. the block has no menu associated with it).
    $is_fallback = false;
    $nav_menu_name = '';
    /**
     * Deprecated:
     * The rgbTextColor and rgbBackgroundColor attributes
     * have been deprecated in favor of
     * customTextColor and customBackgroundColor ones.
     * Move the values from old attrs to the new ones.
     */
    if (isset($attributes['rgbTextColor']) && empty($attributes['textColor'])) {
        $attributes['customTextColor'] = $attributes['rgbTextColor'];
    }
    if (isset($attributes['rgbBackgroundColor']) && empty($attributes['backgroundColor'])) {
        $attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
    }
    unset($attributes['rgbTextColor'], $attributes['rgbBackgroundColor']);
    /**
     * This is for backwards compatibility after `isResponsive` attribute has been removed.
     */
    $has_old_responsive_attribute = !empty($attributes['isResponsive']) && $attributes['isResponsive'];
    $is_responsive_menu = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
    $should_load_view_script = !wp_script_is('wp-block-navigation-view') && ($is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon']);
    if ($should_load_view_script) {
        wp_enqueue_script('wp-block-navigation-view');
    }
    $should_load_modal_view_script = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'];
    if ($should_load_modal_view_script) {
        wp_enqueue_script('wp-block-navigation-view-modal');
    }
    $inner_blocks = $block->inner_blocks;
    // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
    if (array_key_exists('navigationMenuId', $attributes)) {
        $attributes['ref'] = $attributes['navigationMenuId'];
    }
    // If:
    // - the gutenberg plugin is active
    // - `__unstableLocation` is defined
    // - we have menu items at the defined location
    // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
    // ...then create inner blocks from the classic menu assigned to that location.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && array_key_exists('__unstableLocation', $attributes) && !array_key_exists('ref', $attributes) && !empty(block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']))) {
        $menu_items = block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']);
        if (empty($menu_items)) {
            return '';
        }
        $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id($menu_items);
        $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items($menu_items_by_parent_id[0], $menu_items_by_parent_id);
        $inner_blocks = new WP_Block_List($parsed_blocks, $attributes);
    }
    // Load inner blocks from the navigation post.
    if (array_key_exists('ref', $attributes)) {
        $navigation_post = get_post($attributes['ref']);
        if (!isset($navigation_post)) {
            return '';
        }
        // Only published posts are valid. If this is changed then a corresponding change
        // must also be implemented in `use-navigation-menu.js`.
        if ('publish' === $navigation_post->post_status) {
            $nav_menu_name = $navigation_post->post_title;
            if (isset($seen_menu_names[$nav_menu_name])) {
                ++$seen_menu_names[$nav_menu_name];
            } else {
                $seen_menu_names[$nav_menu_name] = 1;
            }
            $parsed_blocks = parse_blocks($navigation_post->post_content);
            // 'parse_blocks' includes a null block with '\n\n' as the content when
            // it encounters whitespace. This code strips it.
            $compacted_blocks = block_core_navigation_filter_out_empty_blocks($parsed_blocks);
            // TODO - this uses the full navigation block attributes for the
            // context which could be refined.
            $inner_blocks = new WP_Block_List($compacted_blocks, $attributes);
        }
    }
    // If there are no inner blocks then fallback to rendering an appropriate fallback.
    if (empty($inner_blocks)) {
        $is_fallback = true;
        // indicate we are rendering the fallback.
        $fallback_blocks = block_core_navigation_get_fallback_blocks();
        // Fallback my have been filtered so do basic test for validity.
        if (empty($fallback_blocks) || !is_array($fallback_blocks)) {
            return '';
        }
        $inner_blocks = new WP_Block_List($fallback_blocks, $attributes);
    }
    /**
     * Filter navigation block $inner_blocks.
     * Allows modification of a navigation block menu items.
     *
     * @since 6.1.0
     *
     * @param \WP_Block_List $inner_blocks
     */
    $inner_blocks = apply_filters('block_core_navigation_render_inner_blocks', $inner_blocks);
    $layout_justification = array('left' => 'items-justified-left', 'right' => 'items-justified-right', 'center' => 'items-justified-center', 'space-between' => 'items-justified-space-between');
    // Restore legacy classnames for submenu positioning.
    $layout_class = '';
    if (isset($attributes['layout']['justifyContent'])) {
        $layout_class .= $layout_justification[$attributes['layout']['justifyContent']];
    }
    if (isset($attributes['layout']['orientation']) && 'vertical' === $attributes['layout']['orientation']) {
        $layout_class .= ' is-vertical';
    }
    if (isset($attributes['layout']['flexWrap']) && 'nowrap' === $attributes['layout']['flexWrap']) {
        $layout_class .= ' no-wrap';
    }
    // Manually add block support text decoration as CSS class.
    $text_decoration = _wp_array_get($attributes, array('style', 'typography', 'textDecoration'), null);
    $text_decoration_class = sprintf('has-text-decoration-%s', $text_decoration);
    $colors = block_core_navigation_build_css_colors($attributes);
    $font_sizes = block_core_navigation_build_css_font_sizes($attributes);
    $classes = array_merge($colors['css_classes'], $font_sizes['css_classes'], $is_responsive_menu ? array('is-responsive') : array(), $layout_class ? array($layout_class) : array(), $is_fallback ? array('is-fallback') : array(), $text_decoration ? array($text_decoration_class) : array());
    $post_ids = block_core_navigation_get_post_ids($inner_blocks);
    if ($post_ids) {
        _prime_post_caches($post_ids, false, false);
    }
    $inner_blocks_html = '';
    $is_list_open = false;
    foreach ($inner_blocks as $inner_block) {
        if (('core/navigation-link' === $inner_block->name || 'core/home-link' === $inner_block->name || 'core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name || 'core/navigation-submenu' === $inner_block->name) && !$is_list_open) {
            $is_list_open = true;
            $inner_blocks_html .= '<ul class="wp-block-navigation__container">';
        }
        if ('core/navigation-link' !== $inner_block->name && 'core/home-link' !== $inner_block->name && 'core/site-title' !== $inner_block->name && 'core/site-logo' !== $inner_block->name && 'core/navigation-submenu' !== $inner_block->name && $is_list_open) {
            $is_list_open = false;
            $inner_blocks_html .= '</ul>';
        }
        $inner_block_content = $inner_block->render();
        if ('core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name && $inner_block_content) {
            $inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block_content . '</li>';
        } else {
            $inner_blocks_html .= $inner_block_content;
        }
    }
    if ($is_list_open) {
        $inner_blocks_html .= '</ul>';
    }
    $block_styles = isset($attributes['styles']) ? $attributes['styles'] : '';
    // If the menu name has been used previously then append an ID
    // to the name to ensure uniqueness across a given post.
    if (isset($seen_menu_names[$nav_menu_name]) && $seen_menu_names[$nav_menu_name] > 1) {
        $count = $seen_menu_names[$nav_menu_name];
        $nav_menu_name = $nav_menu_name . ' ' . $count;
    }
    $wrapper_attributes = get_block_wrapper_attributes(array('class' => implode(' ', $classes), 'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'], 'aria-label' => $nav_menu_name));
    $modal_unique_id = wp_unique_id('modal-');
    // Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
    // return early if they don't.
    if (!$is_responsive_menu) {
        return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $inner_blocks_html);
    }
    $is_hidden_by_default = isset($attributes['overlayMenu']) && 'always' === $attributes['overlayMenu'];
    $responsive_container_classes = array('wp-block-navigation__responsive-container', $is_hidden_by_default ? 'hidden-by-default' : '', implode(' ', $colors['overlay_css_classes']));
    $open_button_classes = array('wp-block-navigation__responsive-container-open', $is_hidden_by_default ? 'always-shown' : '');
    $should_display_icon_label = isset($attributes['hasIcon']) && true === $attributes['hasIcon'];
    $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg>';
    if (isset($attributes['icon'])) {
        if ('menu' === $attributes['icon']) {
            $toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 5v1.5h14V5H5zm0 7.8h14v-1.5H5v1.5zM5 19h14v-1.5H5V19z" /></svg>';
        }
    }
    $toggle_button_content = $should_display_icon_label ? $toggle_button_icon : __('Menu');
    $toggle_close_button_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg>';
    $toggle_close_button_content = $should_display_icon_label ? $toggle_close_button_icon : __('Close');
    $toggle_aria_label_open = $should_display_icon_label ? 'aria-label="' . __('Open menu') . '"' : '';
    // Open button label.
    $toggle_aria_label_close = $should_display_icon_label ? 'aria-label="' . __('Close menu') . '"' : '';
    // Close button label.
    $responsive_container_markup = sprintf('<button aria-haspopup="true" %3$s class="%6$s" data-micromodal-trigger="%1$s">%9$s</button>
			<div class="%5$s" style="%7$s" id="%1$s">
				<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
					<div class="wp-block-navigation__responsive-dialog" aria-label="%8$s">
							<button %4$s data-micromodal-close class="wp-block-navigation__responsive-container-close">%10$s</button>
						<div class="wp-block-navigation__responsive-container-content" id="%1$s-content">
							%2$s
						</div>
					</div>
				</div>
			</div>', esc_attr($modal_unique_id), $inner_blocks_html, $toggle_aria_label_open, $toggle_aria_label_close, esc_attr(implode(' ', $responsive_container_classes)), esc_attr(implode(' ', $open_button_classes)), esc_attr(safecss_filter_attr($colors['overlay_inline_styles'])), __('Menu'), $toggle_button_content, $toggle_close_button_content);
    return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $responsive_container_markup);
}

WordPress Version: 9.5

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array $attributes The block attributes.
 * @param array $content The saved content.
 * @param array $block The parsed block.
 *
 * @return string Returns the post content with the legacy widget added.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    // Flag used to indicate whether the rendered output is considered to be
    // a fallback (i.e. the block has no menu associated with it).
    $is_fallback = false;
    /**
     * Deprecated:
     * The rgbTextColor and rgbBackgroundColor attributes
     * have been deprecated in favor of
     * customTextColor and customBackgroundColor ones.
     * Move the values from old attrs to the new ones.
     */
    if (isset($attributes['rgbTextColor']) && empty($attributes['textColor'])) {
        $attributes['customTextColor'] = $attributes['rgbTextColor'];
    }
    if (isset($attributes['rgbBackgroundColor']) && empty($attributes['backgroundColor'])) {
        $attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
    }
    unset($attributes['rgbTextColor'], $attributes['rgbBackgroundColor']);
    /**
     * This is for backwards compatibility after `isResponsive` attribute has been removed.
     */
    $has_old_responsive_attribute = !empty($attributes['isResponsive']) && $attributes['isResponsive'];
    $is_responsive_menu = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
    $should_load_view_script = !wp_script_is('wp-block-navigation-view') && ($is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon']);
    if ($should_load_view_script) {
        wp_enqueue_script('wp-block-navigation-view');
    }
    $inner_blocks = $block->inner_blocks;
    // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
    if (array_key_exists('navigationMenuId', $attributes)) {
        $attributes['ref'] = $attributes['navigationMenuId'];
    }
    // If:
    // - the gutenberg plugin is active
    // - `__unstableLocation` is defined
    // - we have menu items at the defined location
    // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
    // ...then create inner blocks from the classic menu assigned to that location.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && array_key_exists('__unstableLocation', $attributes) && !array_key_exists('ref', $attributes) && !empty(block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']))) {
        $menu_items = block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']);
        if (empty($menu_items)) {
            return '';
        }
        $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id($menu_items);
        $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items($menu_items_by_parent_id[0], $menu_items_by_parent_id);
        $inner_blocks = new WP_Block_List($parsed_blocks, $attributes);
    }
    // Load inner blocks from the navigation post.
    if (array_key_exists('ref', $attributes)) {
        $navigation_post = get_post($attributes['ref']);
        if (!isset($navigation_post)) {
            return '';
        }
        $parsed_blocks = parse_blocks($navigation_post->post_content);
        // 'parse_blocks' includes a null block with '\n\n' as the content when
        // it encounters whitespace. This code strips it.
        $compacted_blocks = block_core_navigation_filter_out_empty_blocks($parsed_blocks);
        // TODO - this uses the full navigation block attributes for the
        // context which could be refined.
        $inner_blocks = new WP_Block_List($compacted_blocks, $attributes);
    }
    // If there are no inner blocks then fallback to rendering an appropriate fallback.
    if (empty($inner_blocks)) {
        $is_fallback = true;
        // indicate we are rendering the fallback.
        $fallback_blocks = block_core_navigation_get_fallback_blocks();
        // Fallback my have been filtered so do basic test for validity.
        if (empty($fallback_blocks) || !is_array($fallback_blocks)) {
            return '';
        }
        $inner_blocks = new WP_Block_List($fallback_blocks, $attributes);
    }
    $layout_justification = array('left' => 'items-justified-left', 'right' => 'items-justified-right', 'center' => 'items-justified-center', 'space-between' => 'items-justified-space-between');
    // Restore legacy classnames for submenu positioning.
    $layout_class = '';
    if (isset($attributes['layout']['justifyContent'])) {
        $layout_class .= $layout_justification[$attributes['layout']['justifyContent']];
    }
    if (isset($attributes['layout']['orientation']) && 'vertical' === $attributes['layout']['orientation']) {
        $layout_class .= ' is-vertical';
    }
    if (isset($attributes['layout']['flexWrap']) && 'nowrap' === $attributes['layout']['flexWrap']) {
        $layout_class .= ' no-wrap';
    }
    $colors = block_core_navigation_build_css_colors($attributes);
    $font_sizes = block_core_navigation_build_css_font_sizes($attributes);
    $classes = array_merge($colors['css_classes'], $font_sizes['css_classes'], $is_responsive_menu ? array('is-responsive') : array(), $layout_class ? array($layout_class) : array(), $is_fallback ? array('is-fallback') : array());
    $inner_blocks_html = '';
    $is_list_open = false;
    foreach ($inner_blocks as $inner_block) {
        if (('core/navigation-link' === $inner_block->name || 'core/home-link' === $inner_block->name || 'core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name || 'core/navigation-submenu' === $inner_block->name) && !$is_list_open) {
            $is_list_open = true;
            $inner_blocks_html .= '<ul class="wp-block-navigation__container">';
        }
        if ('core/navigation-link' !== $inner_block->name && 'core/home-link' !== $inner_block->name && 'core/site-title' !== $inner_block->name && 'core/site-logo' !== $inner_block->name && 'core/navigation-submenu' !== $inner_block->name && $is_list_open) {
            $is_list_open = false;
            $inner_blocks_html .= '</ul>';
        }
        if ('core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name) {
            $inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block->render() . '</li>';
        } else {
            $inner_blocks_html .= $inner_block->render();
        }
    }
    if ($is_list_open) {
        $inner_blocks_html .= '</ul>';
    }
    $block_styles = isset($attributes['styles']) ? $attributes['styles'] : '';
    $wrapper_attributes = get_block_wrapper_attributes(array('class' => implode(' ', $classes), 'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles']));
    $modal_unique_id = wp_unique_id('modal-');
    // Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
    // return early if they don't.
    if (!$is_responsive_menu) {
        return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $inner_blocks_html);
    }
    $is_hidden_by_default = isset($attributes['overlayMenu']) && 'always' === $attributes['overlayMenu'];
    $responsive_container_classes = array('wp-block-navigation__responsive-container', $is_hidden_by_default ? 'hidden-by-default' : '', implode(' ', $colors['overlay_css_classes']));
    $open_button_classes = array('wp-block-navigation__responsive-container-open', $is_hidden_by_default ? 'always-shown' : '');
    $responsive_container_markup = sprintf(
        '<button aria-haspopup="true" aria-label="%3$s" class="%6$s" data-micromodal-trigger="%1$s"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg></button>
			<div class="%5$s" style="%7$s" id="%1$s">
				<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
					<div class="wp-block-navigation__responsive-dialog" aria-label="%8$s">
							<button aria-label="%4$s" data-micromodal-close class="wp-block-navigation__responsive-container-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg></button>
						<div class="wp-block-navigation__responsive-container-content" id="%1$s-content">
							%2$s
						</div>
					</div>
				</div>
			</div>',
        esc_attr($modal_unique_id),
        $inner_blocks_html,
        __('Open menu'),
        // Open button label.
        __('Close menu'),
        // Close button label.
        esc_attr(implode(' ', $responsive_container_classes)),
        esc_attr(implode(' ', $open_button_classes)),
        esc_attr(safecss_filter_attr($colors['overlay_inline_styles'])),
        __('Menu')
    );
    return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $responsive_container_markup);
}

WordPress Version: 9.3

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array $attributes The block attributes.
 * @param array $content The saved content.
 * @param array $block The parsed block.
 *
 * @return string Returns the post content with the legacy widget added.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    // Flag used to indicate whether the rendered output is considered to be
    // a fallback (i.e. the block has no menu associated with it).
    $is_fallback = false;
    /**
     * Deprecated:
     * The rgbTextColor and rgbBackgroundColor attributes
     * have been deprecated in favor of
     * customTextColor and customBackgroundColor ones.
     * Move the values from old attrs to the new ones.
     */
    if (isset($attributes['rgbTextColor']) && empty($attributes['textColor'])) {
        $attributes['customTextColor'] = $attributes['rgbTextColor'];
    }
    if (isset($attributes['rgbBackgroundColor']) && empty($attributes['backgroundColor'])) {
        $attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
    }
    unset($attributes['rgbTextColor'], $attributes['rgbBackgroundColor']);
    /**
     * This is for backwards compatibility after `isResponsive` attribute has been removed.
     */
    $has_old_responsive_attribute = !empty($attributes['isResponsive']) && $attributes['isResponsive'];
    $is_responsive_menu = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
    $should_load_view_script = !wp_script_is('wp-block-navigation-view') && ($is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon']);
    if ($should_load_view_script) {
        wp_enqueue_script('wp-block-navigation-view');
    }
    $inner_blocks = $block->inner_blocks;
    // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
    if (array_key_exists('navigationMenuId', $attributes)) {
        $attributes['ref'] = $attributes['navigationMenuId'];
    }
    // If:
    // - the gutenberg plugin is active
    // - `__unstableLocation` is defined
    // - we have menu items at the defined location
    // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
    // ...then create inner blocks from the classic menu assigned to that location.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && array_key_exists('__unstableLocation', $attributes) && !array_key_exists('ref', $attributes) && !empty(block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']))) {
        $menu_items = block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']);
        if (empty($menu_items)) {
            return '';
        }
        $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id($menu_items);
        $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items($menu_items_by_parent_id[0], $menu_items_by_parent_id);
        $inner_blocks = new WP_Block_List($parsed_blocks, $attributes);
    }
    // Load inner blocks from the navigation post.
    if (array_key_exists('ref', $attributes)) {
        $navigation_post = get_post($attributes['ref']);
        if (!isset($navigation_post)) {
            return '';
        }
        $parsed_blocks = parse_blocks($navigation_post->post_content);
        // 'parse_blocks' includes a null block with '\n\n' as the content when
        // it encounters whitespace. This code strips it.
        $compacted_blocks = block_core_navigation_filter_out_empty_blocks($parsed_blocks);
        // TODO - this uses the full navigation block attributes for the
        // context which could be refined.
        $inner_blocks = new WP_Block_List($compacted_blocks, $attributes);
    }
    // If there are no inner blocks then fallback to rendering an appropriate fallback.
    if (empty($inner_blocks)) {
        $is_fallback = true;
        // indicate we are rendering the fallback.
        $fallback_blocks = block_core_navigation_get_fallback_blocks();
        // Fallback my have been filtered so do basic test for validity.
        if (empty($fallback_blocks) || !is_array($fallback_blocks)) {
            return '';
        }
        $inner_blocks = new WP_Block_List($fallback_blocks, $attributes);
    }
    $layout_justification = array('left' => 'items-justified-left', 'right' => 'items-justified-right', 'center' => 'items-justified-center', 'space-between' => 'items-justified-space-between');
    // Restore legacy classnames for submenu positioning.
    $layout_class = '';
    if (isset($attributes['layout']['justifyContent'])) {
        $layout_class .= $layout_justification[$attributes['layout']['justifyContent']];
    }
    if (isset($attributes['layout']['orientation']) && 'vertical' === $attributes['layout']['orientation']) {
        $layout_class .= ' is-vertical';
    }
    if (isset($attributes['layout']['flexWrap']) && 'nowrap' === $attributes['layout']['flexWrap']) {
        $layout_class .= ' no-wrap';
    }
    $colors = block_core_navigation_build_css_colors($attributes);
    $font_sizes = block_core_navigation_build_css_font_sizes($attributes);
    $classes = array_merge($colors['css_classes'], $font_sizes['css_classes'], $is_responsive_menu ? array('is-responsive') : array(), $layout_class ? array($layout_class) : array(), $is_fallback ? array('is-fallback') : array());
    $inner_blocks_html = '';
    $is_list_open = false;
    foreach ($inner_blocks as $inner_block) {
        if (('core/navigation-link' === $inner_block->name || 'core/home-link' === $inner_block->name || 'core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name || 'core/navigation-submenu' === $inner_block->name) && !$is_list_open) {
            $is_list_open = true;
            $inner_blocks_html .= '<ul class="wp-block-navigation__container">';
        }
        if ('core/navigation-link' !== $inner_block->name && 'core/home-link' !== $inner_block->name && 'core/site-title' !== $inner_block->name && 'core/site-logo' !== $inner_block->name && 'core/navigation-submenu' !== $inner_block->name && $is_list_open) {
            $is_list_open = false;
            $inner_blocks_html .= '</ul>';
        }
        if ('core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name) {
            $inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block->render() . '</li>';
        } else {
            $inner_blocks_html .= $inner_block->render();
        }
    }
    if ($is_list_open) {
        $inner_blocks_html .= '</ul>';
    }
    $block_styles = isset($attributes['styles']) ? $attributes['styles'] : '';
    $wrapper_attributes = get_block_wrapper_attributes(array('class' => implode(' ', $classes), 'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles']));
    $modal_unique_id = wp_unique_id('modal-');
    // Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
    // return early if they don't.
    if (!$is_responsive_menu) {
        return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $inner_blocks_html);
    }
    $is_hidden_by_default = isset($attributes['overlayMenu']) && 'always' === $attributes['overlayMenu'];
    $responsive_container_classes = array('wp-block-navigation__responsive-container', $is_hidden_by_default ? 'hidden-by-default' : '', implode(' ', $colors['overlay_css_classes']));
    $open_button_classes = array('wp-block-navigation__responsive-container-open', $is_hidden_by_default ? 'always-shown' : '');
    $responsive_container_markup = sprintf(
        '<button aria-haspopup="true" aria-label="%3$s" class="%6$s" data-micromodal-trigger="%1$s"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg></button>
			<div class="%5$s" style="%7$s" id="%1$s">
				<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
					<div class="wp-block-navigation__responsive-dialog" aria-label="%8$s">
							<button aria-label="%4$s" data-micromodal-close class="wp-block-navigation__responsive-container-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg></button>
						<div class="wp-block-navigation__responsive-container-content" id="%1$s-content">
							%2$s
						</div>
					</div>
				</div>
			</div>',
        $modal_unique_id,
        $inner_blocks_html,
        __('Open menu'),
        // Open button label.
        __('Close menu'),
        // Close button label.
        implode(' ', $responsive_container_classes),
        implode(' ', $open_button_classes),
        $colors['overlay_inline_styles'],
        __('Menu')
    );
    return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $responsive_container_markup);
}

WordPress Version: 5.9

/**
 * Renders the `core/navigation` block on server.
 *
 * @param array $attributes The block attributes.
 * @param array $content The saved content.
 * @param array $block The parsed block.
 *
 * @return string Returns the post content with the legacy widget added.
 */
function render_block_core_navigation($attributes, $content, $block)
{
    // Flag used to indicate whether the rendered output is considered to be
    // a fallback (i.e. the block has no menu associated with it).
    $is_fallback = false;
    /**
     * Deprecated:
     * The rgbTextColor and rgbBackgroundColor attributes
     * have been deprecated in favor of
     * customTextColor and customBackgroundColor ones.
     * Move the values from old attrs to the new ones.
     */
    if (isset($attributes['rgbTextColor']) && empty($attributes['textColor'])) {
        $attributes['customTextColor'] = $attributes['rgbTextColor'];
    }
    if (isset($attributes['rgbBackgroundColor']) && empty($attributes['backgroundColor'])) {
        $attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
    }
    unset($attributes['rgbTextColor'], $attributes['rgbBackgroundColor']);
    /**
     * This is for backwards compatibility after `isResponsive` attribute has been removed.
     */
    $has_old_responsive_attribute = !empty($attributes['isResponsive']) && $attributes['isResponsive'];
    $is_responsive_menu = isset($attributes['overlayMenu']) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
    $should_load_view_script = !wp_script_is('wp-block-navigation-view') && ($is_responsive_menu || $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon']);
    if ($should_load_view_script) {
        wp_enqueue_script('wp-block-navigation-view');
    }
    $inner_blocks = $block->inner_blocks;
    // Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
    if (array_key_exists('navigationMenuId', $attributes)) {
        $attributes['ref'] = $attributes['navigationMenuId'];
    }
    // If:
    // - the gutenberg plugin is active
    // - `__unstableLocation` is defined
    // - we have menu items at the defined location
    // - we don't have a relationship to a `wp_navigation` Post (via `ref`).
    // ...then create inner blocks from the classic menu assigned to that location.
    if (defined('IS_GUTENBERG_PLUGIN') && IS_GUTENBERG_PLUGIN && array_key_exists('__unstableLocation', $attributes) && !array_key_exists('ref', $attributes) && !empty(block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']))) {
        $menu_items = block_core_navigation_get_menu_items_at_location($attributes['__unstableLocation']);
        if (empty($menu_items)) {
            return '';
        }
        $menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id($menu_items);
        $parsed_blocks = block_core_navigation_parse_blocks_from_menu_items($menu_items_by_parent_id[0], $menu_items_by_parent_id);
        $inner_blocks = new WP_Block_List($parsed_blocks, $attributes);
    }
    // Load inner blocks from the navigation post.
    if (array_key_exists('ref', $attributes)) {
        $navigation_post = get_post($attributes['ref']);
        if (!isset($navigation_post)) {
            return '';
        }
        $parsed_blocks = parse_blocks($navigation_post->post_content);
        // 'parse_blocks' includes a null block with '\n\n' as the content when
        // it encounters whitespace. This code strips it.
        $compacted_blocks = block_core_navigation_filter_out_empty_blocks($parsed_blocks);
        // TODO - this uses the full navigation block attributes for the
        // context which could be refined.
        $inner_blocks = new WP_Block_List($compacted_blocks, $attributes);
    }
    // If there are no inner blocks then fallback to rendering an appropriate fallback.
    if (empty($inner_blocks)) {
        $is_fallback = true;
        // indicate we are rendering the fallback.
        $fallback_blocks = block_core_navigation_get_fallback_blocks();
        // Fallback my have been filtered so do basic test for validity.
        if (empty($fallback_blocks) || !is_array($fallback_blocks)) {
            return '';
        }
        $inner_blocks = new WP_Block_List($fallback_blocks, $attributes);
    }
    $layout_justification = array('left' => 'items-justified-left', 'right' => 'items-justified-right', 'center' => 'items-justified-center', 'space-between' => 'items-justified-space-between');
    // Restore legacy classnames for submenu positioning.
    $layout_class = '';
    if (isset($attributes['layout']['justifyContent'])) {
        $layout_class .= $layout_justification[$attributes['layout']['justifyContent']];
    }
    if (isset($attributes['layout']['orientation']) && 'vertical' === $attributes['layout']['orientation']) {
        $layout_class .= ' is-vertical';
    }
    if (isset($attributes['layout']['flexWrap']) && 'nowrap' === $attributes['layout']['flexWrap']) {
        $layout_class .= ' no-wrap';
    }
    $colors = block_core_navigation_build_css_colors($attributes);
    $font_sizes = block_core_navigation_build_css_font_sizes($attributes);
    $classes = array_merge($colors['css_classes'], $font_sizes['css_classes'], $is_responsive_menu ? array('is-responsive') : array(), $layout_class ? array($layout_class) : array(), $is_fallback ? array('is-fallback') : array());
    $inner_blocks_html = '';
    $is_list_open = false;
    foreach ($inner_blocks as $inner_block) {
        if (('core/navigation-link' === $inner_block->name || 'core/home-link' === $inner_block->name || 'core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name || 'core/navigation-submenu' === $inner_block->name) && !$is_list_open) {
            $is_list_open = true;
            $inner_blocks_html .= '<ul class="wp-block-navigation__container">';
        }
        if ('core/navigation-link' !== $inner_block->name && 'core/home-link' !== $inner_block->name && 'core/site-title' !== $inner_block->name && 'core/site-logo' !== $inner_block->name && 'core/navigation-submenu' !== $inner_block->name && $is_list_open) {
            $is_list_open = false;
            $inner_blocks_html .= '</ul>';
        }
        if ('core/site-title' === $inner_block->name || 'core/site-logo' === $inner_block->name) {
            $inner_blocks_html .= '<li class="wp-block-navigation-item">' . $inner_block->render() . '</li>';
        } else {
            $inner_blocks_html .= $inner_block->render();
        }
    }
    if ($is_list_open) {
        $inner_blocks_html .= '</ul>';
    }
    $block_styles = isset($attributes['styles']) ? $attributes['styles'] : '';
    $wrapper_attributes = get_block_wrapper_attributes(array('class' => implode(' ', $classes), 'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles']));
    $modal_unique_id = uniqid();
    // Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
    // return early if they don't.
    if (!$is_responsive_menu) {
        return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $inner_blocks_html);
    }
    $is_hidden_by_default = isset($attributes['overlayMenu']) && 'always' === $attributes['overlayMenu'];
    $responsive_container_classes = array('wp-block-navigation__responsive-container', $is_hidden_by_default ? 'hidden-by-default' : '', implode(' ', $colors['overlay_css_classes']));
    $open_button_classes = array('wp-block-navigation__responsive-container-open', $is_hidden_by_default ? 'always-shown' : '');
    $responsive_container_markup = sprintf(
        '<button aria-haspopup="true" aria-label="%3$s" class="%6$s" data-micromodal-trigger="modal-%1$s"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg></button>
			<div class="%5$s" style="%7$s" id="modal-%1$s">
				<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
					<div class="wp-block-navigation__responsive-dialog" aria-label="%8$s">
							<button aria-label="%4$s" data-micromodal-close class="wp-block-navigation__responsive-container-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg></button>
						<div class="wp-block-navigation__responsive-container-content" id="modal-%1$s-content">
							%2$s
						</div>
					</div>
				</div>
			</div>',
        $modal_unique_id,
        $inner_blocks_html,
        __('Open menu'),
        // Open button label.
        __('Close menu'),
        // Close button label.
        implode(' ', $responsive_container_classes),
        implode(' ', $open_button_classes),
        $colors['overlay_inline_styles'],
        __('Menu')
    );
    return sprintf('<nav %1$s>%2$s</nav>', $wrapper_attributes, $responsive_container_markup);
}