From afc8b428853937e1ee0f423b346558adbb649502 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 2 Dec 2022 16:53:19 +0000 Subject: [PATCH] =?UTF-8?q?Recursively=20remove=20Navigation=20block?= =?UTF-8?q?=E2=80=99s=20from=20appearing=20inside=20Navigation=20block=20o?= =?UTF-8?q?n=20front=20of=20site=20(#46279)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Recursively remove Navigation block’s from appearing inside Navigation block content * Fix lint * Use whitelist approach * add a dupliation warning comment * Update packages/block-library/src/navigation/index.php * pacify linter Co-authored-by: Ben Dwyer --- .../src/navigation/edit/inner-blocks.js | 1 + .../block-library/src/navigation/index.php | 48 ++++++++++++++----- 2 files changed, 38 insertions(+), 11 deletions(-) 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.