Skip to content

Commit e225514

Browse files
committed
Block Bindings: Add filter to set supported block attributes.
Add a new filter, `block_bindings_supported_attributes_{$block_type}`, that allows customizing which of a block's attributes can be connected to a Block Bindings source. Props bernhard-reiter, gziolo, maxschmeling. Closes #62090. git-svn-id: https://develop.svn.wordpress.org/trunk@60611 602fd350-edb4-49c9-b593-d223f7449a82
1 parent f152321 commit e225514

File tree

2 files changed

+115
-9
lines changed

2 files changed

+115
-9
lines changed

src/wp-includes/class-wp-block.php

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,22 @@ class WP_Block {
9898
*/
9999
public $inner_content = array();
100100

101+
/**
102+
* List of supported block attributes for block bindings.
103+
*
104+
* @since 6.9.0
105+
* @var array
106+
*
107+
* @see WP_Block::process_block_bindings()
108+
*/
109+
private const BLOCK_BINDINGS_SUPPORTED_ATTRIBUTES = array(
110+
'core/paragraph' => array( 'content' ),
111+
'core/heading' => array( 'content' ),
112+
'core/image' => array( 'id', 'url', 'title', 'alt' ),
113+
'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ),
114+
'core/post-date' => array( 'datetime' ),
115+
);
116+
101117
/**
102118
* Constructor.
103119
*
@@ -278,20 +294,33 @@ public function __get( $name ) {
278294
* @return array The computed block attributes for the provided block bindings.
279295
*/
280296
private function process_block_bindings() {
297+
$block_type = $this->name;
281298
$parsed_block = $this->parsed_block;
282299
$computed_attributes = array();
283-
$supported_block_attributes = array(
284-
'core/paragraph' => array( 'content' ),
285-
'core/heading' => array( 'content' ),
286-
'core/image' => array( 'id', 'url', 'title', 'alt' ),
287-
'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ),
288-
'core/post-date' => array( 'datetime' ),
300+
301+
$supported_block_attributes =
302+
self::BLOCK_BINDINGS_SUPPORTED_ATTRIBUTES[ $block_type ] ??
303+
array();
304+
305+
/**
306+
* Filters the supported block attributes for block bindings.
307+
*
308+
* The dynamic portion of the hook name, `$block_type`, refers to the block type
309+
* whose attributes are being filtered.
310+
*
311+
* @since 6.9.0
312+
*
313+
* @param string[] $supported_block_attributes The block's attributes that are supported by block bindings.
314+
*/
315+
$supported_block_attributes = apply_filters(
316+
"block_bindings_supported_attributes_{$block_type}",
317+
$supported_block_attributes
289318
);
290319

291320
// If the block doesn't have the bindings property, isn't one of the supported
292321
// block types, or the bindings property is not an array, return the block content.
293322
if (
294-
! isset( $supported_block_attributes[ $this->name ] ) ||
323+
empty( $supported_block_attributes ) ||
295324
empty( $parsed_block['attrs']['metadata']['bindings'] ) ||
296325
! is_array( $parsed_block['attrs']['metadata']['bindings'] )
297326
) {
@@ -315,7 +344,7 @@ private function process_block_bindings() {
315344
* Note that this also omits the `__default` attribute from the
316345
* resulting array.
317346
*/
318-
foreach ( $supported_block_attributes[ $parsed_block['blockName'] ] as $attribute_name ) {
347+
foreach ( $supported_block_attributes as $attribute_name ) {
319348
// Retain any non-pattern override bindings that might be present.
320349
$updated_bindings[ $attribute_name ] = isset( $bindings[ $attribute_name ] )
321350
? $bindings[ $attribute_name ]
@@ -334,7 +363,7 @@ private function process_block_bindings() {
334363

335364
foreach ( $bindings as $attribute_name => $block_binding ) {
336365
// If the attribute is not in the supported list, process next attribute.
337-
if ( ! in_array( $attribute_name, $supported_block_attributes[ $this->name ], true ) ) {
366+
if ( ! in_array( $attribute_name, $supported_block_attributes, true ) ) {
338367
continue;
339368
}
340369
// If no source is provided, or that source is not registered, process next attribute.

tests/phpunit/tests/block-bindings/render.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ class WP_Block_Bindings_Render extends WP_UnitTestCase {
1616
'label' => 'Test source',
1717
);
1818

19+
/**
20+
* Sets up shared fixtures.
21+
*
22+
* @since 6.9.0
23+
*/
24+
public static function wpSetUpBeforeClass() {
25+
register_block_type(
26+
'test/block',
27+
array(
28+
'attributes' => array(
29+
'myAttribute' => array(
30+
'type' => 'string',
31+
),
32+
),
33+
'render_callback' => function ( $attributes ) {
34+
return '<p>' . esc_html( $attributes['myAttribute'] ) . '</p>';
35+
},
36+
)
37+
);
38+
}
39+
1940
/**
2041
* Tear down after each test.
2142
*
@@ -31,6 +52,15 @@ public function tear_down() {
3152
parent::tear_down();
3253
}
3354

55+
/**
56+
* Tear down after class.
57+
*
58+
* @since 6.9.0
59+
*/
60+
public static function wpTearDownAfterClass() {
61+
unregister_block_type( 'test/block' );
62+
}
63+
3464
/**
3565
* Test if the block content is updated with the value returned by the source.
3666
*
@@ -72,6 +102,53 @@ public function test_update_block_with_value_from_source() {
72102
);
73103
}
74104

105+
/**
106+
* Test if the block_bindings_supported_attributes_{$block_type} filter is applied correctly.
107+
*
108+
* @ticket 62090
109+
*/
110+
public function test_filter_block_bindings_supported_attributes() {
111+
$get_value_callback = function () {
112+
return 'test source value';
113+
};
114+
115+
register_block_bindings_source(
116+
self::SOURCE_NAME,
117+
array(
118+
'label' => self::SOURCE_LABEL,
119+
'get_value_callback' => $get_value_callback,
120+
)
121+
);
122+
123+
add_filter(
124+
'block_bindings_supported_attributes_test/block',
125+
function ( $supported_attributes ) {
126+
$supported_attributes[] = 'myAttribute';
127+
return $supported_attributes;
128+
}
129+
);
130+
131+
$block_content = <<<HTML
132+
<!-- wp:test/block {"metadata":{"bindings":{"myAttribute":{"source":"test/source"}}}} -->
133+
<p>This should not appear</p>
134+
<!-- /wp:test/block -->
135+
HTML;
136+
$parsed_blocks = parse_blocks( $block_content );
137+
$block = new WP_Block( $parsed_blocks[0] );
138+
$result = $block->render();
139+
140+
$this->assertSame(
141+
'test source value',
142+
$block->attributes['myAttribute'],
143+
"The 'myAttribute' attribute should be updated with the value returned by the source."
144+
);
145+
$this->assertSame(
146+
'<p>test source value</p>',
147+
trim( $result ),
148+
'The block content should be updated with the value returned by the source.'
149+
);
150+
}
151+
75152
/**
76153
* Test passing arguments to the source.
77154
*

0 commit comments

Comments
 (0)