Skip to content

Commit bd32e51

Browse files
committed
get_block_wrapper_attributes(): Preserve zero value
1 parent 3d9fde3 commit bd32e51

File tree

3 files changed

+184
-57
lines changed

3 files changed

+184
-57
lines changed

src/wp-includes/blocks.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,68 @@ function get_block_asset_url( $path ) {
127127
return plugins_url( basename( $path ), $path );
128128
}
129129

130+
/**
131+
* Generates a string of attributes by applying to the current block being
132+
* rendered all of the features that the block supports.
133+
*
134+
* @since 5.6.0
135+
*
136+
* @param string[] $extra_attributes Optional. Array of extra attributes to render on the block wrapper.
137+
* @return string String of HTML attributes.
138+
*/
139+
function get_block_wrapper_attributes( $extra_attributes = array() ) {
140+
$new_attributes = WP_Block_Supports::get_instance()->apply_block_supports();
141+
142+
if ( empty( $new_attributes ) && empty( $extra_attributes ) ) {
143+
return '';
144+
}
145+
146+
// This is hardcoded on purpose.
147+
// We only support a fixed list of attributes.
148+
$attributes_to_merge = array( 'style', 'class', 'id', 'aria-label' );
149+
$attributes = array();
150+
foreach ( $attributes_to_merge as $attribute_name ) {
151+
$new_value = array_key_exists( $attribute_name, $new_attributes ) ? (string) $new_attributes[ $attribute_name ] : '';
152+
$extra_value = array_key_exists( $attribute_name, $extra_attributes ) ? (string) $extra_attributes[ $attribute_name ] : '';
153+
154+
if ( '' === $new_value && '' === $extra_value ) {
155+
continue;
156+
}
157+
158+
if ( '' === $new_value ) {
159+
$attributes[ $attribute_name ] = $extra_value;
160+
continue;
161+
}
162+
163+
if ( '' === $extra_value ) {
164+
$attributes[ $attribute_name ] = $new_value;
165+
continue;
166+
}
167+
168+
$attributes[ $attribute_name ] = $extra_value . ' ' . $new_value;
169+
}
170+
171+
foreach ( $extra_attributes as $attribute_name => $value ) {
172+
if ( ! in_array( $attribute_name, $attributes_to_merge, true ) ) {
173+
$string_value = (string) $value;
174+
if ( '' !== $string_value ) {
175+
$attributes[ $attribute_name ] = $string_value;
176+
}
177+
}
178+
}
179+
180+
if ( empty( $attributes ) ) {
181+
return '';
182+
}
183+
184+
$normalized_attributes = array();
185+
foreach ( $attributes as $key => $value ) {
186+
$normalized_attributes[] = $key . '="' . esc_attr( $value ) . '"';
187+
}
188+
189+
return implode( ' ', $normalized_attributes );
190+
}
191+
130192
/**
131193
* Finds a script module ID for the selected block metadata field. It detects
132194
* when a path to file was provided and optionally finds a corresponding asset

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

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public function apply_block_supports() {
121121

122122
if ( ! empty( $new_attributes ) ) {
123123
foreach ( $new_attributes as $attribute_name => $attribute_value ) {
124-
if ( empty( $output[ $attribute_name ] ) ) {
124+
if ( ! array_key_exists( $attribute_name, $output ) || '' === (string) $output[ $attribute_name ] ) {
125125
$output[ $attribute_name ] = $attribute_value;
126126
} else {
127127
$output[ $attribute_name ] .= " $attribute_value";
@@ -162,59 +162,3 @@ private function register_attributes() {
162162
}
163163
}
164164
}
165-
166-
/**
167-
* Generates a string of attributes by applying to the current block being
168-
* rendered all of the features that the block supports.
169-
*
170-
* @since 5.6.0
171-
*
172-
* @param string[] $extra_attributes Optional. Array of extra attributes to render on the block wrapper.
173-
* @return string String of HTML attributes.
174-
*/
175-
function get_block_wrapper_attributes( $extra_attributes = array() ) {
176-
$new_attributes = WP_Block_Supports::get_instance()->apply_block_supports();
177-
178-
if ( empty( $new_attributes ) && empty( $extra_attributes ) ) {
179-
return '';
180-
}
181-
182-
// This is hardcoded on purpose.
183-
// We only support a fixed list of attributes.
184-
$attributes_to_merge = array( 'style', 'class', 'id', 'aria-label' );
185-
$attributes = array();
186-
foreach ( $attributes_to_merge as $attribute_name ) {
187-
if ( empty( $new_attributes[ $attribute_name ] ) && empty( $extra_attributes[ $attribute_name ] ) ) {
188-
continue;
189-
}
190-
191-
if ( empty( $new_attributes[ $attribute_name ] ) ) {
192-
$attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ];
193-
continue;
194-
}
195-
196-
if ( empty( $extra_attributes[ $attribute_name ] ) ) {
197-
$attributes[ $attribute_name ] = $new_attributes[ $attribute_name ];
198-
continue;
199-
}
200-
201-
$attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ] . ' ' . $new_attributes[ $attribute_name ];
202-
}
203-
204-
foreach ( $extra_attributes as $attribute_name => $value ) {
205-
if ( ! in_array( $attribute_name, $attributes_to_merge, true ) ) {
206-
$attributes[ $attribute_name ] = $value;
207-
}
208-
}
209-
210-
if ( empty( $attributes ) ) {
211-
return '';
212-
}
213-
214-
$normalized_attributes = array();
215-
foreach ( $attributes as $key => $value ) {
216-
$normalized_attributes[] = $key . '="' . esc_attr( $value ) . '"';
217-
}
218-
219-
return implode( ' ', $normalized_attributes );
220-
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
/**
3+
* Tests for get_block_wrapper_attributes function.
4+
*
5+
* @package WordPress
6+
* @subpackage Blocks
7+
*
8+
* @since 7.0.0
9+
*
10+
* @group blocks
11+
* @covers ::get_block_wrapper_attributes
12+
*/
13+
class Tests_Blocks_GetBlockWrapperAttributes extends WP_UnitTestCase {
14+
15+
/**
16+
* Tear down after each test.
17+
*
18+
* @since 7.0.0
19+
*/
20+
public function tear_down() {
21+
$registry = WP_Block_Type_Registry::get_instance();
22+
if ( $registry->is_registered( 'core/example' ) ) {
23+
$registry->unregister( 'core/example' );
24+
}
25+
if ( $registry->is_registered( 'core/example' ) ) {
26+
$registry->unregister( 'core/example' );
27+
}
28+
29+
parent::tear_down();
30+
}
31+
32+
/**
33+
* @ticket 64452
34+
*/
35+
public function test_preserves_zero_values() {
36+
WP_Block_Supports::init();
37+
register_block_type(
38+
'core/example',
39+
array(
40+
'supports' => array(
41+
'customClassName' => true,
42+
'ariaLabel' => true,
43+
),
44+
)
45+
);
46+
WP_Block_Supports::$block_to_render = array(
47+
'blockName' => 'core/example',
48+
'attrs' => array(
49+
'className' => '0',
50+
'ariaLabel' => 0,
51+
),
52+
);
53+
$result = get_block_wrapper_attributes();
54+
$this->assertSame( 'class="0 wp-block-example" aria-label="0"', $result );
55+
}
56+
57+
/**
58+
* @ticket 64452
59+
*/
60+
public function test_preserves_zero_values_from_extra_attributes() {
61+
WP_Block_Supports::init();
62+
register_block_type( 'core/example' );
63+
WP_Block_Supports::$block_to_render = array( 'blockName' => 'core/example' );
64+
65+
$result = get_block_wrapper_attributes(
66+
array(
67+
'class' => '0',
68+
'aria-label' => 0,
69+
'data-foo' => 0,
70+
'data-var' => '0',
71+
)
72+
);
73+
$this->assertSame( 'class="0 wp-block-example" aria-label="0" data-foo="0" data-var="0"', $result );
74+
}
75+
76+
/**
77+
* @ticket 64452
78+
*/
79+
public function test_excludes_falsy_values_except_zero() {
80+
WP_Block_Supports::init();
81+
register_block_type(
82+
'core/example',
83+
array(
84+
'supports' => array(
85+
'customClassName' => true,
86+
'ariaLabel' => true,
87+
),
88+
)
89+
);
90+
WP_Block_Supports::$block_to_render = array(
91+
'blockName' => 'core/example',
92+
'attrs' => array(
93+
'className' => false,
94+
'ariaLabel' => null,
95+
),
96+
);
97+
98+
$result = get_block_wrapper_attributes();
99+
$this->assertSame( 'class="wp-block-example"', $result, );
100+
}
101+
102+
/**
103+
* @ticket 64452
104+
*/
105+
public function test_excludes_falsy_values_except_zero_from_extra_attributes() {
106+
WP_Block_Supports::init();
107+
register_block_type( 'core/example' );
108+
WP_Block_Supports::$block_to_render = array( 'blockName' => 'core/example' );
109+
110+
$result = get_block_wrapper_attributes(
111+
array(
112+
'class' => false,
113+
'aria-label' => null,
114+
'data-var' => false,
115+
'data-baz' => null,
116+
)
117+
);
118+
$this->assertSame( 'class="wp-block-example"', $result );
119+
}
120+
}
121+

0 commit comments

Comments
 (0)