Skip to content

Commit 7ae00bc

Browse files
noisysocksaslamdoctor
authored andcommitted
Block themes: Enable block-level background image styles
Allows defining background images for blocks in theme.json. Syncs PHP changes from WordPress/gutenberg#60100. Props ramonopoly, aaronrobertshaw. Fixes #61588. git-svn-id: https://develop.svn.wordpress.org/trunk@58797 602fd350-edb4-49c9-b593-d223f7449a82
1 parent be28ce5 commit 7ae00bc

File tree

6 files changed

+164
-15
lines changed

6 files changed

+164
-15
lines changed

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ function wp_render_background_support( $block_content, $block ) {
6262
return $block_content;
6363
}
6464

65-
$background_styles = array();
66-
$background_styles['backgroundImage'] = isset( $block_attributes['style']['background']['backgroundImage'] ) ? $block_attributes['style']['background']['backgroundImage'] : array();
65+
$background_styles = array();
66+
$background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null;
67+
$background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null;
68+
$background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null;
69+
$background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null;
6770

6871
if ( ! empty( $background_styles['backgroundImage'] ) ) {
69-
$background_styles['backgroundSize'] = isset( $block_attributes['style']['background']['backgroundSize'] ) ? $block_attributes['style']['background']['backgroundSize'] : 'cover';
70-
$background_styles['backgroundPosition'] = isset( $block_attributes['style']['background']['backgroundPosition'] ) ? $block_attributes['style']['background']['backgroundPosition'] : null;
71-
$background_styles['backgroundRepeat'] = isset( $block_attributes['style']['background']['backgroundRepeat'] ) ? $block_attributes['style']['background']['backgroundRepeat'] : null;
72+
$background_styles['backgroundSize'] = $background_styles['backgroundSize'] ?? 'cover';
7273

7374
// If the background size is set to `contain` and no position is set, set the position to `center`.
7475
if ( 'contain' === $background_styles['backgroundSize'] && ! $background_styles['backgroundPosition'] ) {

src/wp-includes/class-wp-theme-json-resolver.php

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,7 @@ public static function get_style_variations( $scope = 'theme' ) {
848848
* as the value of `_link` object in REST API responses.
849849
*
850850
* @since 6.6.0
851+
* @since 6.7.0 Resolve relative paths in block styles.
851852
*
852853
* @param WP_Theme_JSON $theme_json A theme json instance.
853854
* @return array An array of resolved paths.
@@ -860,15 +861,14 @@ public static function get_resolved_theme_uris( $theme_json ) {
860861
}
861862

862863
$theme_json_data = $theme_json->get_raw_data();
863-
864-
// Top level styles.
865-
$background_image_url = isset( $theme_json_data['styles']['background']['backgroundImage']['url'] ) ? $theme_json_data['styles']['background']['backgroundImage']['url'] : null;
866-
867864
/*
868865
* The same file convention when registering web fonts.
869866
* See: WP_Font_Face_Resolver::to_theme_file_uri.
870867
*/
871868
$placeholder = 'file:./';
869+
870+
// Top level styles.
871+
$background_image_url = $theme_json_data['styles']['background']['backgroundImage']['url'] ?? null;
872872
if (
873873
isset( $background_image_url ) &&
874874
is_string( $background_image_url ) &&
@@ -888,6 +888,33 @@ public static function get_resolved_theme_uris( $theme_json ) {
888888
$resolved_theme_uris[] = $resolved_theme_uri;
889889
}
890890

891+
// Block styles.
892+
if ( ! empty( $theme_json_data['styles']['blocks'] ) ) {
893+
foreach ( $theme_json_data['styles']['blocks'] as $block_name => $block_styles ) {
894+
if ( ! isset( $block_styles['background']['backgroundImage']['url'] ) ) {
895+
continue;
896+
}
897+
$background_image_url = $block_styles['background']['backgroundImage']['url'];
898+
if (
899+
is_string( $background_image_url ) &&
900+
// Skip if the src doesn't start with the placeholder, as there's nothing to replace.
901+
str_starts_with( $background_image_url, $placeholder )
902+
) {
903+
$file_type = wp_check_filetype( $background_image_url );
904+
$src_url = str_replace( $placeholder, '', $background_image_url );
905+
$resolved_theme_uri = array(
906+
'name' => $background_image_url,
907+
'href' => sanitize_url( get_theme_file_uri( $src_url ) ),
908+
'target' => "styles.blocks.{$block_name}.background.backgroundImage.url",
909+
);
910+
if ( isset( $file_type['type'] ) ) {
911+
$resolved_theme_uri['type'] = $file_type['type'];
912+
}
913+
$resolved_theme_uris[] = $resolved_theme_uri;
914+
}
915+
}
916+
}
917+
891918
return $resolved_theme_uris;
892919
}
893920

src/wp-includes/class-wp-theme-json.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -520,10 +520,10 @@ class WP_Theme_JSON {
520520
*/
521521
const VALID_STYLES = array(
522522
'background' => array(
523-
'backgroundImage' => 'top',
524-
'backgroundPosition' => 'top',
525-
'backgroundRepeat' => 'top',
526-
'backgroundSize' => 'top',
523+
'backgroundImage' => null,
524+
'backgroundPosition' => null,
525+
'backgroundRepeat' => null,
526+
'backgroundSize' => null,
527527
),
528528
'border' => array(
529529
'color' => null,

src/wp-includes/global-styles-and-settings.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,15 @@ function wp_get_global_stylesheet( $types = array() ) {
247247
* Adds global style rules to the inline style for each block.
248248
*
249249
* @since 6.1.0
250+
* @since 6.7.0 Resolve relative paths in block styles.
250251
*
251252
* @global WP_Styles $wp_styles
252253
*/
253254
function wp_add_global_styles_for_blocks() {
254255
global $wp_styles;
255256

256257
$tree = WP_Theme_JSON_Resolver::get_merged_data();
258+
$tree = WP_Theme_JSON_Resolver::resolve_theme_file_uris( $tree );
257259
$block_nodes = $tree->get_styles_block_nodes();
258260
foreach ( $block_nodes as $metadata ) {
259261
$block_css = $tree->get_styles_for_block( $metadata );

tests/phpunit/tests/theme/wpThemeJson.php

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5021,7 +5021,7 @@ public function test_get_top_level_background_image_styles() {
50215021
);
50225022

50235023
$expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}";
5024-
$this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_stylesheet()" with top-level background styles type does not match expectations' );
5024+
$this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_stylesheet()" with top-level background styles type do not match expectations' );
50255025

50265026
$theme_json = new WP_Theme_JSON(
50275027
array(
@@ -5038,7 +5038,64 @@ public function test_get_top_level_background_image_styles() {
50385038
);
50395039

50405040
$expected_styles = "html{min-height: calc(100% - var(--wp-admin--admin-bar--height, 0px));}:root :where(body){background-image: url('http://example.org/image.png');background-position: center center;background-repeat: no-repeat;background-size: contain;}";
5041-
$this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_stylesheet()" with top-level background image as string type does not match expectations' );
5041+
$this->assertSame( $expected_styles, $theme_json->get_styles_for_block( $body_node ), 'Styles returned from "::get_stylesheet()" with top-level background image as string type do not match expectations' );
5042+
}
5043+
5044+
/**
5045+
* @ticket 61588
5046+
*/
5047+
public function test_get_block_background_image_styles() {
5048+
$theme_json = new WP_Theme_JSON(
5049+
array(
5050+
'version' => WP_Theme_JSON::LATEST_SCHEMA,
5051+
'styles' => array(
5052+
'blocks' => array(
5053+
'core/group' => array(
5054+
'background' => array(
5055+
'backgroundImage' => "url('http://example.org/group.png')",
5056+
'backgroundSize' => 'cover',
5057+
'backgroundRepeat' => 'no-repeat',
5058+
'backgroundPosition' => 'center center',
5059+
),
5060+
),
5061+
'core/quote' => array(
5062+
'background' => array(
5063+
'backgroundImage' => array(
5064+
'url' => 'http://example.org/quote.png',
5065+
),
5066+
'backgroundSize' => 'cover',
5067+
'backgroundRepeat' => 'no-repeat',
5068+
'backgroundPosition' => 'center center',
5069+
),
5070+
),
5071+
),
5072+
),
5073+
)
5074+
);
5075+
5076+
$quote_node = array(
5077+
'name' => 'core/quote',
5078+
'path' => array( 'styles', 'blocks', 'core/quote' ),
5079+
'selector' => '.wp-block-quote',
5080+
'selectors' => array(
5081+
'root' => '.wp-block-quote',
5082+
),
5083+
);
5084+
5085+
$quote_styles = ":root :where(.wp-block-quote){background-image: url('http://example.org/quote.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}";
5086+
$this->assertSame( $quote_styles, $theme_json->get_styles_for_block( $quote_node ), 'Styles returned from "::get_styles_for_block()" with block-level background styles do not match expectations' );
5087+
5088+
$group_node = array(
5089+
'name' => 'core/group',
5090+
'path' => array( 'styles', 'blocks', 'core/group' ),
5091+
'selector' => '.wp-block-group',
5092+
'selectors' => array(
5093+
'root' => '.wp-block-group',
5094+
),
5095+
);
5096+
5097+
$group_styles = ":root :where(.wp-block-group){background-image: url('http://example.org/group.png');background-position: center center;background-repeat: no-repeat;background-size: cover;}";
5098+
$this->assertSame( $group_styles, $theme_json->get_styles_for_block( $group_node ), 'Styles returned from "::get_styles_for_block()" with block-level background styles as string type do not match expectations' );
50425099
}
50435100

50445101
/**

tests/phpunit/tests/theme/wpThemeJsonResolver.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ public function test_shadow_default_presets_value_for_block_and_classic_themes()
12571257
*
12581258
* @covers WP_Theme_JSON_Resolver::resolve_theme_file_uris
12591259
* @ticket 61273
1260+
* @ticket 61588
12601261
*/
12611262
public function test_resolve_theme_file_uris() {
12621263
$theme_json = new WP_Theme_JSON(
@@ -1268,6 +1269,22 @@ public function test_resolve_theme_file_uris() {
12681269
'url' => 'file:./assets/image.png',
12691270
),
12701271
),
1272+
'blocks' => array(
1273+
'core/quote' => array(
1274+
'background' => array(
1275+
'backgroundImage' => array(
1276+
'url' => 'file:./assets/quote.png',
1277+
),
1278+
),
1279+
),
1280+
'core/verse' => array(
1281+
'background' => array(
1282+
'backgroundImage' => array(
1283+
'url' => 'file:./assets/verse.png',
1284+
),
1285+
),
1286+
),
1287+
),
12711288
),
12721289
)
12731290
);
@@ -1280,6 +1297,22 @@ public function test_resolve_theme_file_uris() {
12801297
'url' => 'https://example.org/wp-content/themes/example-theme/assets/image.png',
12811298
),
12821299
),
1300+
'blocks' => array(
1301+
'core/quote' => array(
1302+
'background' => array(
1303+
'backgroundImage' => array(
1304+
'url' => 'https://example.org/wp-content/themes/example-theme/assets/quote.png',
1305+
),
1306+
),
1307+
),
1308+
'core/verse' => array(
1309+
'background' => array(
1310+
'backgroundImage' => array(
1311+
'url' => 'https://example.org/wp-content/themes/example-theme/assets/verse.png',
1312+
),
1313+
),
1314+
),
1315+
),
12831316
),
12841317
);
12851318

@@ -1293,6 +1326,7 @@ public function test_resolve_theme_file_uris() {
12931326
*
12941327
* @covers WP_Theme_JSON_Resolver::get_resolved_theme_uris
12951328
* @ticket 61273
1329+
* @ticket 61588
12961330
*/
12971331
public function test_get_resolved_theme_uris() {
12981332
$theme_json = new WP_Theme_JSON(
@@ -1304,6 +1338,22 @@ public function test_get_resolved_theme_uris() {
13041338
'url' => 'file:./assets/image.png',
13051339
),
13061340
),
1341+
'blocks' => array(
1342+
'core/quote' => array(
1343+
'background' => array(
1344+
'backgroundImage' => array(
1345+
'url' => 'file:./assets/quote.jpg',
1346+
),
1347+
),
1348+
),
1349+
'core/verse' => array(
1350+
'background' => array(
1351+
'backgroundImage' => array(
1352+
'url' => 'file:./assets/verse.gif',
1353+
),
1354+
),
1355+
),
1356+
),
13071357
),
13081358
)
13091359
);
@@ -1315,6 +1365,18 @@ public function test_get_resolved_theme_uris() {
13151365
'target' => 'styles.background.backgroundImage.url',
13161366
'type' => 'image/png',
13171367
),
1368+
array(
1369+
'name' => 'file:./assets/quote.jpg',
1370+
'href' => 'https://example.org/wp-content/themes/example-theme/assets/quote.jpg',
1371+
'target' => 'styles.blocks.core/quote.background.backgroundImage.url',
1372+
'type' => 'image/jpeg',
1373+
),
1374+
array(
1375+
'name' => 'file:./assets/verse.gif',
1376+
'href' => 'https://example.org/wp-content/themes/example-theme/assets/verse.gif',
1377+
'target' => 'styles.blocks.core/verse.background.backgroundImage.url',
1378+
'type' => 'image/gif',
1379+
),
13181380
);
13191381

13201382
$actual = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme_json );

0 commit comments

Comments
 (0)