Skip to content

Commit dccfac1

Browse files
ockhamgziolo
andauthored
Block Bindings: Fix a bug in the back-compat layer (#71691)
Co-authored-by: ockham <[email protected]> Co-authored-by: gziolo <[email protected]>
1 parent 45f5bab commit dccfac1

File tree

3 files changed

+51
-16
lines changed

3 files changed

+51
-16
lines changed

backport-changelog/6.9/9469.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
https://github.com/WordPress/wordpress-develop/pull/9469
22

33
* https://github.com/WordPress/gutenberg/pull/71389
4+
* https://github.com/WordPress/gutenberg/pull/71691

lib/compat/wordpress-6.9/block-bindings.php

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,39 @@ function gutenberg_block_bindings_render_block( $block_content, $block, $instanc
3636
return $block_content;
3737
}
3838

39-
$attributes = $instance->parsed_block['attrs'];
4039
// Process the block bindings and get attributes updated with the values from the sources.
4140
$computed_attributes = gutenberg_process_block_bindings( $instance );
4241
if ( empty( $computed_attributes ) ) {
4342
return $block_content;
4443
}
4544

46-
// Merge the computed attributes with the original attributes.
47-
$instance->attributes = array_merge( $attributes, $computed_attributes );
45+
/*
46+
* Merge the computed attributes with the original attributes.
47+
*
48+
* Note that this is not a recursive merge, meaning that nested attributes --
49+
* such as block bindings metadata -- will be completely replaced.
50+
* This is desirable. At this point, Core has already processed any block
51+
* bindings that it supports. What remains to be processed are only the attributes
52+
* for which support was added later (through the `block_bindings_supported_attributes`
53+
* filter). To do so, we'll run `$instance->render()` once more
54+
* so the block can update its content based on those attributes.
55+
*/
56+
$instance->attributes = array_merge( $instance->attributes, $computed_attributes );
57+
58+
/*
59+
* If we're dealing with the Button block, we remove the bindings metadata
60+
* in order to avoid having it reprocessed, which would lead to Core
61+
* capitalizing the wrapper tag (e.g. <DIV>).
62+
*/
63+
if ( 'core/button' === $instance->name ) {
64+
unset( $instance->parsed_block['attrs']['metadata']['bindings'] );
65+
}
4866

4967
/**
50-
* This filter is called from WP_Block::render(), after the block content has
51-
* already been rendered. However, dynamic blocks expect their render() method
52-
* to receive block attributes to have their bound values. This means that we have
53-
* to re-render the block here.
54-
* To do so, we'll set a flag that this filter checks when invoked to avoid infinite
55-
* recursion. Furthermore, we can unset all of the block's bindings, as we know that
56-
* they have been processed by the time we reach this point.
68+
* This filter (`gutenberg_block_bindings_render_block`) is called from `WP_Block::render()`.
69+
* To avoid infinite recursion, we set a flag that this filter checks when invoked which tells
70+
* it to exit early.
5771
*/
58-
unset( $instance->parsed_block['attrs']['metadata']['bindings'] );
5972
$inside_block_bindings_render = true;
6073
$block_content = $instance->render();
6174
$inside_block_bindings_render = false;

phpunit/block-bindings-test.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ function ( $supported_attributes ) {
4545
return $supported_attributes;
4646
}
4747
);
48+
49+
add_filter(
50+
'block_bindings_supported_attributes_core/image',
51+
function ( $supported_attributes ) {
52+
$supported_attributes[] = 'caption';
53+
return $supported_attributes;
54+
}
55+
);
4856
}
4957

5058
/**
@@ -259,11 +267,19 @@ public function test_passing_uses_context_to_source() {
259267
* Tests if the block content is updated with the value returned by the source
260268
* for the Image block in the placeholder state.
261269
*
270+
* Furthermore tests if the caption attribute, for which support is added via the
271+
* `block_bindings_supported_attributes_core/image` filter, is correctly processed.
272+
*
262273
* @covers ::register_block_bindings_source
263274
*/
264275
public function test_update_block_with_value_from_source_image_placeholder() {
265-
$get_value_callback = function () {
266-
return 'https://example.com/image.jpg';
276+
$get_value_callback = function ( $source_args, $block_instance, $attribute_name ) {
277+
if ( 'url' === $attribute_name ) {
278+
return 'https://example.com/image.jpg';
279+
}
280+
if ( 'caption' === $attribute_name ) {
281+
return 'Example Image';
282+
}
267283
};
268284

269285
register_block_bindings_source(
@@ -275,8 +291,8 @@ public function test_update_block_with_value_from_source_image_placeholder() {
275291
);
276292

277293
$block_content = <<<HTML
278-
<!-- wp:image {"metadata":{"bindings":{"url":{"source":"test/source"}}}} -->
279-
<figure class="wp-block-image"><img alt=""/></figure>
294+
<!-- wp:image {"metadata":{"bindings":{"url":{"source":"test/source"},"caption":{"source":"test/source"}}}} -->
295+
<figure class="wp-block-image"><img alt=""/><figcaption class="wp-element-caption"></figcaption></figure>
280296
<!-- /wp:image -->
281297
HTML;
282298
$parsed_blocks = parse_blocks( $block_content );
@@ -289,7 +305,12 @@ public function test_update_block_with_value_from_source_image_placeholder() {
289305
"The 'url' attribute should be updated with the value returned by the source."
290306
);
291307
$this->assertSame(
292-
'<figure class="wp-block-image"><img src="https://example.com/image.jpg" alt=""/></figure>',
308+
'Example Image',
309+
$block->attributes['caption'],
310+
"The 'caption' attribute should be updated with the value returned by the source."
311+
);
312+
$this->assertSame(
313+
'<figure class="wp-block-image"><img src="https://example.com/image.jpg" alt=""/><figcaption class="wp-element-caption">Example Image</figcaption></figure>',
293314
trim( $result ),
294315
'The block content should be updated with the value returned by the source.'
295316
);

0 commit comments

Comments
 (0)