diff --git a/lib/navigation.php b/lib/navigation.php index b1e7d21b031589..7bfe3416647c6e 100644 --- a/lib/navigation.php +++ b/lib/navigation.php @@ -299,9 +299,14 @@ function gutenberg_output_block_nav_menu( $output, $args ) { $menu_items_by_parent_id[ $menu_item->menu_item_parent ][] = $menu_item; } + $block_attributes = array(); + if ( isset( $args->block_attributes ) ) { + $block_attributes = $args->block_attributes; + } + $navigation_block = array( 'blockName' => 'core/navigation', - 'attrs' => array(), + 'attrs' => $block_attributes, 'innerBlocks' => gutenberg_convert_menu_items_to_blocks( isset( $menu_items_by_parent_id[0] ) ? $menu_items_by_parent_id[0] diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json index 28c7d25a89ea68..a354926b635b5f 100644 --- a/packages/block-library/src/navigation/block.json +++ b/packages/block-library/src/navigation/block.json @@ -3,6 +3,9 @@ "name": "core/navigation", "category": "design", "attributes": { + "location": { + "type": "string" + }, "orientation": { "type": "string" }, diff --git a/packages/block-library/src/navigation/edit.js b/packages/block-library/src/navigation/edit.js index 18d9da732015c9..961cde395d570e 100644 --- a/packages/block-library/src/navigation/edit.js +++ b/packages/block-library/src/navigation/edit.js @@ -100,6 +100,8 @@ function Navigation( { return (
{ setIsPlaceholderShown( false ); updateInnerBlocks( blocks ); diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index b1fe553df3b3fb..be166b3894a4be 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -85,6 +85,41 @@ function block_core_navigation_build_css_font_sizes( $attributes ) { return $font_sizes; } +/** + * Renders a Navigation Block derived from data from the theme_location assigned + * via the block attribute 'location'. + * + * If the theme doesn't explicity support 'block-nav-menus' or no location was provided + * as a block attribute then an empty string is returned. + * + * @param array $attributes Navigation block attributes. + * @return string HTML markup of a generated Navigation Block. + */ +function get_classic_navigation_elements( $attributes ) { + + if ( ! current_theme_supports( 'block-nav-menus' ) ) { + return ''; + } + + if ( ! array_key_exists( 'location', $attributes ) ) { + return ''; + } + + $block_attributes = $attributes; + unset( $block_attributes['location'] ); + + return wp_nav_menu( + array( + 'theme_location' => $attributes['location'], + 'block_attributes' => $block_attributes, + 'container' => '', + 'items_wrap' => '%3$s', + 'fallback_cb' => false, + 'echo' => false, + ) + ); +} + /** * Returns the top-level submenu SVG chevron icon. * @@ -122,7 +157,7 @@ function render_block_core_navigation( $attributes, $content, $block ) { unset( $attributes['rgbTextColor'], $attributes['rgbBackgroundColor'] ); if ( empty( $block->inner_blocks ) ) { - return ''; + return get_classic_navigation_elements( $attributes ); } $colors = block_core_navigation_build_css_colors( $attributes ); diff --git a/packages/block-library/src/navigation/placeholder.js b/packages/block-library/src/navigation/placeholder.js index c0ac1b6ff4c301..eb6a853ad0ae4b 100644 --- a/packages/block-library/src/navigation/placeholder.js +++ b/packages/block-library/src/navigation/placeholder.js @@ -98,7 +98,7 @@ function convertMenuItemsToBlocks( menuItems ) { return mapMenuItemsToBlocks( menuTree ); } -function NavigationPlaceholder( { onCreate }, ref ) { +function NavigationPlaceholder( { location, onCreate, setAttributes }, ref ) { const [ selectedMenu, setSelectedMenu ] = useState(); const [ isCreatingFromMenu, setIsCreatingFromMenu ] = useState( false ); @@ -108,6 +108,7 @@ function NavigationPlaceholder( { onCreate }, ref ) { isResolvingPages, hasResolvedPages, menus, + menuLocations, isResolvingMenus, hasResolvedMenus, menuItems, @@ -118,6 +119,7 @@ function NavigationPlaceholder( { onCreate }, ref ) { getEntityRecords, getMenus, getMenuItems, + getMenuLocations, isResolving, hasFinishedResolution, } = select( coreStore ); @@ -167,6 +169,7 @@ function NavigationPlaceholder( { onCreate }, ref ) { menuItemsParameters ) : false, + menuLocations: getMenuLocations(), }; }, [ selectedMenu ] @@ -216,6 +219,131 @@ function NavigationPlaceholder( { onCreate }, ref ) { isPrimary: true, className: 'wp-block-navigation-placeholder__actions__dropdown', }; + + const locationPlaceholder = () => { + if ( ! location || ! menuLocations ) { + return; + } + + const selectedMenuLocation = menuLocations.find( + ( menuLocation ) => menuLocation.name === location + ); + + if ( ! selectedMenuLocation ) { + return; + } + + return ( + <> + { ' ' } + + { ( { onClose } ) => ( + + { menuLocations.map( ( { name, description } ) => { + return ( + { + setAttributes( { location: name } ); + onClose(); + } } + isSelected={ name === location } + onClose={ onClose } + key={ name } + > + { description } + + ); + } ) } + + ) } + + + + + ); + }; + + const convertToBlocks = () => { + setAttributes( { location: null } ); + }; + + const convertToClassic = ( newLocation ) => { + setAttributes( { location: newLocation.name } ); + }; + + const defaultPlaceholder = () => { + if ( location ) { + return; + } + + const defaultClassicMenuLocation = menuLocations?.[ 0 ]; + + return ( + <> + { hasMenus ? ( + + { ( { onClose } ) => ( + + { menus.map( ( menu ) => { + return ( + { + setSelectedMenu( menu.id ); + onCreateFromMenu(); + } } + onClose={ onClose } + key={ menu.id } + > + { menu.name } + + ); + } ) } + + ) } + + ) : undefined } + + { hasPages ? ( + + ) : undefined } + + { !! defaultClassicMenuLocation ? ( + + ) : null } + + ); + }; + return (
@@ -234,46 +362,9 @@ function NavigationPlaceholder( { onCreate }, ref ) {
{ __( 'Navigation' ) }
- { hasMenus ? ( - - { ( { onClose } ) => ( - - { menus.map( ( menu ) => { - return ( - { - setSelectedMenu( - menu.id - ); - onCreateFromMenu(); - } } - onClose={ onClose } - key={ menu.id } - > - { menu.name } - - ); - } ) } - - ) } - - ) : undefined } - { hasPages ? ( - - ) : undefined } - + + { locationPlaceholder() } + { defaultPlaceholder() }
) }