wpseek.com
A WordPress-centric search engine for devs and theme authors
render_block_core_navigation › WordPress Function
Sincen/a
Deprecatedn/a
› render_block_core_navigation ( $attributes, $content, $block )
Parameters: (3) |
|
Returns: |
|
Defined at: |
|
Codex: |
Renders the `core/navigation` block on server.
Source
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_directives = ' data-wp-interactive data-wp-context=\'{ "core": { "navigation": { "overlayOpenedBy": {}, "type": "overlay", "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.ariaModal" 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" %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"> <div class="wp-block-navigation__responsive-dialog" aria-label="%8$s" %13$s> <button %4$s 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 ); }