From bababb94e2dc4e113ca952a8c3e4fe697c25fef5 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 24 Jan 2024 17:10:09 +0100 Subject: [PATCH 1/4] Update Navigation block to render hooked inner blocks --- .../wordpress-6.5/navigation-block-hooks.php | 112 ++++++++++++++++++ lib/load.php | 1 + .../block-library/src/navigation/index.php | 25 +++- 3 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 lib/compat/wordpress-6.5/navigation-block-hooks.php diff --git a/lib/compat/wordpress-6.5/navigation-block-hooks.php b/lib/compat/wordpress-6.5/navigation-block-hooks.php new file mode 100644 index 00000000000000..d7a0e888622d25 --- /dev/null +++ b/lib/compat/wordpress-6.5/navigation-block-hooks.php @@ -0,0 +1,112 @@ += 6.4 +// that have not yet been included in Gutenberg's compatibility layer (lib/compat/wordpress-6.4/block-hooks.php). +if ( function_exists( 'get_hooked_blocks' ) ) { + add_filter( 'rest_prepare_wp_navigation', 'gutenberg_hook_blocks_into_core_navigation_rest_response', 10, 3 ); + add_action( 'rest_insert_wp_navigation', 'gutenberg_update_ignore_hooked_blocks_meta_core_navigation', 10, 3 ); +} + +/** + * Updates the post meta with the list of ignored hooked blocks when the navigation is created or updated via the REST API. + * + * @param WP_Post $post Post object. + */ +function gutenberg_update_ignore_hooked_blocks_meta_core_navigation( $post ) { + if ( ! isset( $post->ID ) ) { + return; + } + + // We run the Block Hooks mechanism so it will return the list of ignored hooked blocks + // in the mock root Navigation block's metadata attribute. + // We ignore the rest of the returned `$markup`; `$post->post_content` already has the hooked + // blocks inserted, whereas `$markup` will have them inserted twice. + $blocks = parse_blocks( $post->post_content ); + $markup = gutenberg_insert_hooked_blocks_into_navigation_block( $blocks, $post ); + $root_nav_block = parse_blocks( $markup )[0]; + $ignored_hooked_blocks = isset( $root_nav_block['attrs']['metadata']['ignoredHookedBlocks'] ) + ? $root_nav_block['attrs']['metadata']['ignoredHookedBlocks'] + : array(); + + if ( ! empty( $ignored_hooked_blocks ) ) { + $existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); + if ( ! empty( $existing_ignored_hooked_blocks ) ) { + $existing_ignored_hooked_blocks = json_decode( $existing_ignored_hooked_blocks, true ); + $ignored_hooked_blocks = array_unique( array_merge( $ignored_hooked_blocks, $existing_ignored_hooked_blocks ) ); + } + update_post_meta( $post->ID, '_wp_ignored_hooked_blocks', json_encode( $ignored_hooked_blocks ) ); + } +} + +/** + * Hooks into the REST API response for the core/navigation block and adds the first and last inner blocks. + * + * @param WP_REST_Response $response The response object. + * @param WP_Post $post Post object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response The response object. + */ +function gutenberg_hook_blocks_into_core_navigation_rest_response( $response, $post ) { + if ( ! isset( $response->data['content']['raw'] ) || ! isset( $response->data['content']['rendered'] ) ) { + return $response; + } + $parsed_blocks = parse_blocks( $response->data['content']['raw'] ); + $content = gutenberg_insert_hooked_blocks_into_navigation_block( $parsed_blocks, $post ); + + // Remove mock Navigation block wrapper. + $start = strpos( $content, '-->' ) + strlen( '-->' ); + $end = strrpos( $content, '' ) + strlen( '-->' ); @@ -78,7 +78,7 @@ function gutenberg_hook_blocks_into_core_navigation_rest_response( $response, $p * @param WP_Post $post `wp_navigation` post object corresponding to the block. * @return string Serialized inner blocks in mock Navigation block wrapper, with hooked blocks inserted, if any. */ -function gutenberg_insert_hooked_blocks_into_navigation_block( $inner_blocks, $post = null ) { +function block_core_navigation_insert_hooked_blocks( $inner_blocks, $post = null ) { $before_block_visitor = null; $after_block_visitor = null; $hooked_blocks = get_hooked_blocks(); diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php index 6df3cbf98dc752..96fc55623904e4 100644 --- a/packages/block-library/src/navigation/index.php +++ b/packages/block-library/src/navigation/index.php @@ -194,7 +194,7 @@ private static function get_inner_blocks_from_navigation_post( $attributes ) { if ( function_exists( 'get_hooked_blocks' ) ) { // Run Block Hooks algorithm to inject hooked blocks. - $markup = gutenberg_insert_hooked_blocks_into_navigation_block( $blocks, $navigation_post ); + $markup = block_core_navigation_insert_hooked_blocks( $blocks, $navigation_post ); $root_nav_block = parse_blocks( $markup )[0]; $blocks = isset( $root_nav_block['innerBlocks'] ) ? $root_nav_block['innerBlocks'] : $blocks; @@ -995,7 +995,7 @@ function block_core_navigation_get_fallback_blocks() { if ( function_exists( 'get_hooked_blocks' ) ) { // Run Block Hooks algorithm to inject hooked blocks. // We have to run it here because we need the post ID of the Navigation block to track ignored hooked blocks. - $markup = gutenberg_insert_hooked_blocks_into_navigation_block( $fallback_blocks, $navigation_post ); + $markup = block_core_navigation_insert_hooked_blocks( $fallback_blocks, $navigation_post ); $blocks = parse_blocks( $markup ); if ( isset( $blocks[0]['innerBlocks'] ) ) { From e4818315307e95103ad2bb93003365a74108d2b4 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 24 Jan 2024 17:50:11 +0100 Subject: [PATCH 3/4] Rename other functions --- lib/compat/wordpress-6.5/navigation-block-hooks.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/compat/wordpress-6.5/navigation-block-hooks.php b/lib/compat/wordpress-6.5/navigation-block-hooks.php index 9e1879a6dd080d..e691144a392a3e 100644 --- a/lib/compat/wordpress-6.5/navigation-block-hooks.php +++ b/lib/compat/wordpress-6.5/navigation-block-hooks.php @@ -2,8 +2,8 @@ // Injection of hooked blocks into the Navigation block relies on some functions present in WP >= 6.4 // that have not yet been included in Gutenberg's compatibility layer (lib/compat/wordpress-6.4/block-hooks.php). if ( function_exists( 'get_hooked_blocks' ) ) { - add_filter( 'rest_prepare_wp_navigation', 'gutenberg_hook_blocks_into_core_navigation_rest_response', 10, 3 ); - add_action( 'rest_insert_wp_navigation', 'gutenberg_update_ignore_hooked_blocks_meta_core_navigation', 10, 3 ); + add_filter( 'rest_prepare_wp_navigation', 'block_core_navigation_insert_hooked_blocks_into_rest_response', 10, 3 ); + add_action( 'rest_insert_wp_navigation', 'block_core_navigation_update_ignore_hooked_blocks_meta', 10, 3 ); } /** @@ -11,7 +11,7 @@ * * @param WP_Post $post Post object. */ -function gutenberg_update_ignore_hooked_blocks_meta_core_navigation( $post ) { +function block_core_navigation_update_ignore_hooked_blocks_meta( $post ) { if ( ! isset( $post->ID ) ) { return; } @@ -45,7 +45,7 @@ function gutenberg_update_ignore_hooked_blocks_meta_core_navigation( $post ) { * @param WP_REST_Request $request Request object. * @return WP_REST_Response The response object. */ -function gutenberg_hook_blocks_into_core_navigation_rest_response( $response, $post ) { +function block_core_navigation_insert_hooked_blocks_into_rest_response( $response, $post ) { if ( ! isset( $response->data['content']['raw'] ) || ! isset( $response->data['content']['rendered'] ) ) { return $response; } From 2933ca24b84f7b4b3c43131b2447b0389bed0cc0 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 24 Jan 2024 17:54:40 +0100 Subject: [PATCH 4/4] Move all code into Nav block --- .../wordpress-6.5/navigation-block-hooks.php | 112 ----------------- lib/load.php | 1 - .../block-library/src/navigation/index.php | 117 ++++++++++++++++++ 3 files changed, 117 insertions(+), 113 deletions(-) delete mode 100644 lib/compat/wordpress-6.5/navigation-block-hooks.php diff --git a/lib/compat/wordpress-6.5/navigation-block-hooks.php b/lib/compat/wordpress-6.5/navigation-block-hooks.php deleted file mode 100644 index e691144a392a3e..00000000000000 --- a/lib/compat/wordpress-6.5/navigation-block-hooks.php +++ /dev/null @@ -1,112 +0,0 @@ -= 6.4 -// that have not yet been included in Gutenberg's compatibility layer (lib/compat/wordpress-6.4/block-hooks.php). -if ( function_exists( 'get_hooked_blocks' ) ) { - add_filter( 'rest_prepare_wp_navigation', 'block_core_navigation_insert_hooked_blocks_into_rest_response', 10, 3 ); - add_action( 'rest_insert_wp_navigation', 'block_core_navigation_update_ignore_hooked_blocks_meta', 10, 3 ); -} - -/** - * Updates the post meta with the list of ignored hooked blocks when the navigation is created or updated via the REST API. - * - * @param WP_Post $post Post object. - */ -function block_core_navigation_update_ignore_hooked_blocks_meta( $post ) { - if ( ! isset( $post->ID ) ) { - return; - } - - // We run the Block Hooks mechanism so it will return the list of ignored hooked blocks - // in the mock root Navigation block's metadata attribute. - // We ignore the rest of the returned `$markup`; `$post->post_content` already has the hooked - // blocks inserted, whereas `$markup` will have them inserted twice. - $blocks = parse_blocks( $post->post_content ); - $markup = block_core_navigation_insert_hooked_blocks( $blocks, $post ); - $root_nav_block = parse_blocks( $markup )[0]; - $ignored_hooked_blocks = isset( $root_nav_block['attrs']['metadata']['ignoredHookedBlocks'] ) - ? $root_nav_block['attrs']['metadata']['ignoredHookedBlocks'] - : array(); - - if ( ! empty( $ignored_hooked_blocks ) ) { - $existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); - if ( ! empty( $existing_ignored_hooked_blocks ) ) { - $existing_ignored_hooked_blocks = json_decode( $existing_ignored_hooked_blocks, true ); - $ignored_hooked_blocks = array_unique( array_merge( $ignored_hooked_blocks, $existing_ignored_hooked_blocks ) ); - } - update_post_meta( $post->ID, '_wp_ignored_hooked_blocks', json_encode( $ignored_hooked_blocks ) ); - } -} - -/** - * Hooks into the REST API response for the core/navigation block and adds the first and last inner blocks. - * - * @param WP_REST_Response $response The response object. - * @param WP_Post $post Post object. - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response The response object. - */ -function block_core_navigation_insert_hooked_blocks_into_rest_response( $response, $post ) { - if ( ! isset( $response->data['content']['raw'] ) || ! isset( $response->data['content']['rendered'] ) ) { - return $response; - } - $parsed_blocks = parse_blocks( $response->data['content']['raw'] ); - $content = block_core_navigation_insert_hooked_blocks( $parsed_blocks, $post ); - - // Remove mock Navigation block wrapper. - $start = strpos( $content, '-->' ) + strlen( '-->' ); - $end = strrpos( $content, '' ) + strlen( '-->' ); + $end = strrpos( $content, '