diff --git a/packages/block-library/src/navigation/edit/inner-blocks.js b/packages/block-library/src/navigation/edit/inner-blocks.js index cb7f9a171f72ad..c06d1196e37ccf 100644 --- a/packages/block-library/src/navigation/edit/inner-blocks.js +++ b/packages/block-library/src/navigation/edit/inner-blocks.js @@ -15,6 +15,7 @@ import { useMemo } from '@wordpress/element'; */ import PlaceholderPreview from './placeholder/placeholder-preview'; +// This list is duplicated in packages/block-library/src/navigation/index.php const ALLOWED_BLOCKS = [ 'core/navigation-link', 'core/search', diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index 34c4769c3ab9f6..8cb9728fe37f28 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -384,20 +384,45 @@ function block_core_navigation_get_most_recently_published_navigation() { } /** - * Filter out empty "null" blocks from the block list. - * 'parse_blocks' includes a null block with '\n\n' as the content when + * Recursively filter out blocks from the block list that are not whitelisted. + * This list of exclusions includes: + * - The Navigation block itself (results in recursion). + * - empty "null" blocks from the block list. + * - other blocks that are not yet handled. + * + * Note: 'parse_blocks' includes a null block with '\n\n' as the content when * it encounters whitespace. This is not a bug but rather how the parser * is designed. * - * @param array $parsed_blocks the parsed blocks to be normalized. - * @return array the normalized parsed blocks. + * @param array $parsed_blocks the parsed blocks to be filtered. + * @return array the filtered parsed blocks. */ -function block_core_navigation_filter_out_empty_blocks( $parsed_blocks ) { - $filtered = array_filter( +function block_core_navigation_filter_out_invalid_blocks( $parsed_blocks ) { + // This list is duplicated in /packages/block-library/src/navigation/edit/inner-blocks.js. + $allowed_blocks = array( + 'core/navigation-link', + 'core/search', + 'core/social-links', + 'core/page-list', + 'core/spacer', + 'core/home-link', + 'core/site-title', + 'core/site-logo', + 'core/navigation-submenu', + ); + + $filtered = array_reduce( $parsed_blocks, - function( $block ) { - return isset( $block['blockName'] ); - } + function( $carry, $block ) use ( $allowed_blocks ) { + if ( isset( $block['blockName'] ) && in_array( $block['blockName'], $allowed_blocks, true ) ) { + if ( $block['innerBlocks'] ) { + $block['innerBlocks'] = block_core_navigation_filter_out_invalid_blocks( $block['innerBlocks'] ); + } + $carry[] = $block; + } + return $carry; + }, + array() ); // Reset keys. @@ -437,7 +462,8 @@ function block_core_navigation_get_fallback_blocks() { // Use the first non-empty Navigation as fallback if available. if ( $navigation_post ) { - $maybe_fallback = block_core_navigation_filter_out_empty_blocks( parse_blocks( $navigation_post->post_content ) ); + + $maybe_fallback = block_core_navigation_filter_out_invalid_blocks( parse_blocks( $navigation_post->post_content ) ); // Normalizing blocks may result in an empty array of blocks if they were all `null` blocks. // In this case default to the (Page List) fallback. @@ -595,7 +621,7 @@ function render_block_core_navigation( $attributes, $content, $block ) { // '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 ); + $compacted_blocks = block_core_navigation_filter_out_invalid_blocks( $parsed_blocks ); // TODO - this uses the full navigation block attributes for the // context which could be refined.