Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin: Ensure that Block Hooks work correctly after landing in WP core #54651

Merged
merged 2 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 31 additions & 27 deletions lib/compat/wordpress-6.4/block-hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ function gutenberg_add_hooked_blocks( $settings, $metadata ) {

return $settings;
}
add_filter( 'block_type_metadata_settings', 'gutenberg_add_hooked_blocks', 10, 2 );

/**
* Register a hooked block for automatic insertion into a given block hook.
Expand Down Expand Up @@ -256,7 +255,6 @@ function gutenberg_parse_and_serialize_block_templates( $query_result ) {

return $query_result;
}
add_filter( 'get_block_templates', 'gutenberg_parse_and_serialize_block_templates', 10, 1 );

/**
* Filters the block template object after it has been (potentially) fetched from the theme file.
Expand All @@ -279,7 +277,37 @@ function gutenberg_parse_and_serialize_blocks( $block_template ) {

return $block_template;
}
add_filter( 'get_block_file_template', 'gutenberg_parse_and_serialize_blocks', 10, 1 );

/**
* Register the `block_hooks` field for the block-types REST API controller.
*
* @return void
*/
function gutenberg_register_block_hooks_rest_field() {
register_rest_field(
'block-type',
'block_hooks',
array(
'schema' => array(
'description' => __( 'This block is automatically inserted near any occurence of the block types used as keys of this map, into a relative position given by the corresponding value.', 'gutenberg' ),
'patternProperties' => array(
'^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$' => array(
'type' => 'string',
'enum' => array( 'before', 'after', 'first_child', 'last_child' ),
),
),
),
)
);
}

// Install the polyfill for Block Hooks only if it isn't already handled in WordPress core.
if ( ! function_exists( 'traverse_and_serialize_blocks' ) ) {
add_filter( 'block_type_metadata_settings', 'gutenberg_add_hooked_blocks', 10, 2 );
add_filter( 'get_block_templates', 'gutenberg_parse_and_serialize_block_templates', 10, 1 );
add_filter( 'get_block_file_template', 'gutenberg_parse_and_serialize_blocks', 10, 1 );
add_action( 'rest_api_init', 'gutenberg_register_block_hooks_rest_field' );
}

// Helper functions.
// -----------------
Expand Down Expand Up @@ -345,27 +373,3 @@ function gutenberg_serialize_block( $block ) {
function gutenberg_serialize_blocks( $blocks ) {
return implode( '', array_map( 'gutenberg_serialize_block', $blocks ) );
}

/**
* Register the `block_hooks` field for the block-types REST API controller.
*
* @return void
*/
function gutenberg_register_block_hooks_rest_field() {
register_rest_field(
'block-type',
'block_hooks',
array(
'schema' => array(
'description' => __( 'This block is automatically inserted near any occurence of the block types used as keys of this map, into a relative position given by the corresponding value.', 'gutenberg' ),
'patternProperties' => array(
'^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$' => array(
'type' => 'string',
'enum' => array( 'before', 'after', 'first_child', 'last_child' ),
),
),
),
)
);
}
add_action( 'rest_api_init', 'gutenberg_register_block_hooks_rest_field' );
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class Gutenberg_REST_Block_Patterns_Controller extends Gutenberg_REST_Block_Patt
public function prepare_item_for_response( $item, $request ) {
$response = parent::prepare_item_for_response( $item, $request );

// Run the polyfill for Block Hooks only if it isn't already handled in WordPress core.
if ( function_exists( 'traverse_and_serialize_blocks' ) ) {
return $response;
}

$data = $response->get_data();

if ( empty( $data['content'] ) ) {
Expand Down
8 changes: 4 additions & 4 deletions packages/block-library/src/pattern/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ function render_block_core_pattern( $attributes ) {
}

$pattern = $registry->get_registered( $slug );
$content = _inject_theme_attribute_in_block_template_content( $pattern['content'] );
$content = $pattern['content'];

// Backward compatibility for handling Block Hooks and injecting the theme attribute in the Gutenberg plugin.
// This can be removed when the minimum supported WordPress is >= 6.4.
if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
// TODO: In the long run, we'd likely want to have a filter in the `WP_Block_Patterns_Registry` class
// instead to allow us plugging in code like this.
if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN && ! function_exists( 'traverse_and_serialize_blocks' ) ) {
$content = _inject_theme_attribute_in_block_template_content( $content );
$blocks = parse_blocks( $content );
$content = gutenberg_serialize_blocks( $blocks );
}
Expand Down
12 changes: 10 additions & 2 deletions phpunit/tests/blocks/renderHookedBlocks.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<?php

use PHP_CodeSniffer\Generators\HTML;

/**
* Tests for hooked blocks rendering.
*
Expand All @@ -12,6 +10,16 @@
* @group blocks
*/
class Tests_Blocks_RenderHookedBlocks extends WP_UnitTestCase {
public function set_up() {
parent::set_up();
add_filter( 'block_type_metadata_settings', 'gutenberg_add_hooked_blocks', 10, 2 );
}

public function tear_down() {
remove_filter( 'block_type_metadata_settings', 'gutenberg_add_hooked_blocks' );
parent::tear_down();
}

/**
* @ticket 59313
*/
Expand Down
Loading