Skip to content

Commit

Permalink
Block themes: Enable block-level background image styles
Browse files Browse the repository at this point in the history
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
  • Loading branch information
noisysocks committed Jul 24, 2024
1 parent 15c34f5 commit a8915f8
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 15 deletions.
11 changes: 6 additions & 5 deletions src/wp-includes/block-supports/background.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ function wp_render_background_support( $block_content, $block ) {
return $block_content;
}

$background_styles = array();
$background_styles['backgroundImage'] = isset( $block_attributes['style']['background']['backgroundImage'] ) ? $block_attributes['style']['background']['backgroundImage'] : array();
$background_styles = array();
$background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null;
$background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null;
$background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null;
$background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null;

if ( ! empty( $background_styles['backgroundImage'] ) ) {
$background_styles['backgroundSize'] = isset( $block_attributes['style']['background']['backgroundSize'] ) ? $block_attributes['style']['background']['backgroundSize'] : 'cover';
$background_styles['backgroundPosition'] = isset( $block_attributes['style']['background']['backgroundPosition'] ) ? $block_attributes['style']['background']['backgroundPosition'] : null;
$background_styles['backgroundRepeat'] = isset( $block_attributes['style']['background']['backgroundRepeat'] ) ? $block_attributes['style']['background']['backgroundRepeat'] : null;
$background_styles['backgroundSize'] = $background_styles['backgroundSize'] ?? 'cover';

// If the background size is set to `contain` and no position is set, set the position to `center`.
if ( 'contain' === $background_styles['backgroundSize'] && ! $background_styles['backgroundPosition'] ) {
Expand Down
35 changes: 31 additions & 4 deletions src/wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,7 @@ public static function get_style_variations( $scope = 'theme' ) {
* as the value of `_link` object in REST API responses.
*
* @since 6.6.0
* @since 6.7.0 Resolve relative paths in block styles.
*
* @param WP_Theme_JSON $theme_json A theme json instance.
* @return array An array of resolved paths.
Expand All @@ -860,15 +861,14 @@ public static function get_resolved_theme_uris( $theme_json ) {
}

$theme_json_data = $theme_json->get_raw_data();

// Top level styles.
$background_image_url = isset( $theme_json_data['styles']['background']['backgroundImage']['url'] ) ? $theme_json_data['styles']['background']['backgroundImage']['url'] : null;

/*
* The same file convention when registering web fonts.
* See: WP_Font_Face_Resolver::to_theme_file_uri.
*/
$placeholder = 'file:./';

// Top level styles.
$background_image_url = $theme_json_data['styles']['background']['backgroundImage']['url'] ?? null;
if (
isset( $background_image_url ) &&
is_string( $background_image_url ) &&
Expand All @@ -888,6 +888,33 @@ public static function get_resolved_theme_uris( $theme_json ) {
$resolved_theme_uris[] = $resolved_theme_uri;
}

// Block styles.
if ( ! empty( $theme_json_data['styles']['blocks'] ) ) {
foreach ( $theme_json_data['styles']['blocks'] as $block_name => $block_styles ) {
if ( ! isset( $block_styles['background']['backgroundImage']['url'] ) ) {
continue;
}
$background_image_url = $block_styles['background']['backgroundImage']['url'];
if (
is_string( $background_image_url ) &&
// Skip if the src doesn't start with the placeholder, as there's nothing to replace.
str_starts_with( $background_image_url, $placeholder )
) {
$file_type = wp_check_filetype( $background_image_url );
$src_url = str_replace( $placeholder, '', $background_image_url );
$resolved_theme_uri = array(
'name' => $background_image_url,
'href' => sanitize_url( get_theme_file_uri( $src_url ) ),
'target' => "styles.blocks.{$block_name}.background.backgroundImage.url",
);
if ( isset( $file_type['type'] ) ) {
$resolved_theme_uri['type'] = $file_type['type'];
}
$resolved_theme_uris[] = $resolved_theme_uri;
}
}
}

return $resolved_theme_uris;
}

Expand Down
8 changes: 4 additions & 4 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,10 @@ class WP_Theme_JSON {
*/
const VALID_STYLES = array(
'background' => array(
'backgroundImage' => 'top',
'backgroundPosition' => 'top',
'backgroundRepeat' => 'top',
'backgroundSize' => 'top',
'backgroundImage' => null,
'backgroundPosition' => null,
'backgroundRepeat' => null,
'backgroundSize' => null,
),
'border' => array(
'color' => null,
Expand Down
2 changes: 2 additions & 0 deletions src/wp-includes/global-styles-and-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,15 @@ function wp_get_global_stylesheet( $types = array() ) {
* Adds global style rules to the inline style for each block.
*
* @since 6.1.0
* @since 6.7.0 Resolve relative paths in block styles.
*
* @global WP_Styles $wp_styles
*/
function wp_add_global_styles_for_blocks() {
global $wp_styles;

$tree = WP_Theme_JSON_Resolver::get_merged_data();
$tree = WP_Theme_JSON_Resolver::resolve_theme_file_uris( $tree );
$block_nodes = $tree->get_styles_block_nodes();
foreach ( $block_nodes as $metadata ) {
$block_css = $tree->get_styles_for_block( $metadata );
Expand Down
61 changes: 59 additions & 2 deletions tests/phpunit/tests/theme/wpThemeJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -5021,7 +5021,7 @@ public function test_get_top_level_background_image_styles() {
);

$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;}";
$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' );
$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' );

$theme_json = new WP_Theme_JSON(
array(
Expand All @@ -5038,7 +5038,64 @@ public function test_get_top_level_background_image_styles() {
);

$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;}";
$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' );
$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' );
}

/**
* @ticket 61588
*/
public function test_get_block_background_image_styles() {
$theme_json = new WP_Theme_JSON(
array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'styles' => array(
'blocks' => array(
'core/group' => array(
'background' => array(
'backgroundImage' => "url('http://example.org/group.png')",
'backgroundSize' => 'cover',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
),
),
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'http://example.org/quote.png',
),
'backgroundSize' => 'cover',
'backgroundRepeat' => 'no-repeat',
'backgroundPosition' => 'center center',
),
),
),
),
)
);

$quote_node = array(
'name' => 'core/quote',
'path' => array( 'styles', 'blocks', 'core/quote' ),
'selector' => '.wp-block-quote',
'selectors' => array(
'root' => '.wp-block-quote',
),
);

$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;}";
$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' );

$group_node = array(
'name' => 'core/group',
'path' => array( 'styles', 'blocks', 'core/group' ),
'selector' => '.wp-block-group',
'selectors' => array(
'root' => '.wp-block-group',
),
);

$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;}";
$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' );
}

/**
Expand Down
62 changes: 62 additions & 0 deletions tests/phpunit/tests/theme/wpThemeJsonResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,7 @@ public function test_shadow_default_presets_value_for_block_and_classic_themes()
*
* @covers WP_Theme_JSON_Resolver::resolve_theme_file_uris
* @ticket 61273
* @ticket 61588
*/
public function test_resolve_theme_file_uris() {
$theme_json = new WP_Theme_JSON(
Expand All @@ -1268,6 +1269,22 @@ public function test_resolve_theme_file_uris() {
'url' => 'file:./assets/image.png',
),
),
'blocks' => array(
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./assets/quote.png',
),
),
),
'core/verse' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./assets/verse.png',
),
),
),
),
),
)
);
Expand All @@ -1280,6 +1297,22 @@ public function test_resolve_theme_file_uris() {
'url' => 'https://example.org/wp-content/themes/example-theme/assets/image.png',
),
),
'blocks' => array(
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'https://example.org/wp-content/themes/example-theme/assets/quote.png',
),
),
),
'core/verse' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'https://example.org/wp-content/themes/example-theme/assets/verse.png',
),
),
),
),
),
);

Expand All @@ -1293,6 +1326,7 @@ public function test_resolve_theme_file_uris() {
*
* @covers WP_Theme_JSON_Resolver::get_resolved_theme_uris
* @ticket 61273
* @ticket 61588
*/
public function test_get_resolved_theme_uris() {
$theme_json = new WP_Theme_JSON(
Expand All @@ -1304,6 +1338,22 @@ public function test_get_resolved_theme_uris() {
'url' => 'file:./assets/image.png',
),
),
'blocks' => array(
'core/quote' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./assets/quote.jpg',
),
),
),
'core/verse' => array(
'background' => array(
'backgroundImage' => array(
'url' => 'file:./assets/verse.gif',
),
),
),
),
),
)
);
Expand All @@ -1315,6 +1365,18 @@ public function test_get_resolved_theme_uris() {
'target' => 'styles.background.backgroundImage.url',
'type' => 'image/png',
),
array(
'name' => 'file:./assets/quote.jpg',
'href' => 'https://example.org/wp-content/themes/example-theme/assets/quote.jpg',
'target' => 'styles.blocks.core/quote.background.backgroundImage.url',
'type' => 'image/jpeg',
),
array(
'name' => 'file:./assets/verse.gif',
'href' => 'https://example.org/wp-content/themes/example-theme/assets/verse.gif',
'target' => 'styles.blocks.core/verse.background.backgroundImage.url',
'type' => 'image/gif',
),
);

$actual = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme_json );
Expand Down

0 comments on commit a8915f8

Please sign in to comment.