Make WordPress Core

Changeset 58797


Ignore:
Timestamp:
07/24/2024 12:24:31 AM (17 months ago)
Author:
noisysocks
Message:

Block themes: Enable block-level background image styles

Allows defining background images for blocks in theme.json.

Syncs PHP changes from https://github.com/WordPress/gutenberg/pull/60100.

Props ramonopoly, aaronrobertshaw.
Fixes #61588.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/block-supports/background.php

    r58222 r58797  
    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`.
  • trunk/src/wp-includes/class-wp-theme-json-resolver.php

    r58468 r58797  
    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.
     
    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.
     
    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 ) &&
     
    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    }
  • trunk/src/wp-includes/class-wp-theme-json.php

    r58749 r58797  
    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(
  • trunk/src/wp-includes/global-styles-and-settings.php

    r58710 r58797  
    248248 *
    249249 * @since 6.1.0
     250 * @since 6.7.0 Resolve relative paths in block styles.
    250251 *
    251252 * @global WP_Styles $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 ) {
  • trunk/tests/phpunit/tests/theme/wpThemeJson.php

    r58749 r58797  
    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(
     
    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
  • trunk/tests/phpunit/tests/theme/wpThemeJsonResolver.php

    r58466 r58797  
    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() {
     
    12671268                        'backgroundImage' => array(
    12681269                            'url' => 'file:./assets/image.png',
     1270                        ),
     1271                    ),
     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                            ),
    12691286                        ),
    12701287                    ),
     
    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        );
     
    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() {
     
    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            )
     
    13151365                'target' => 'styles.background.backgroundImage.url',
    13161366                'type'   => 'image/png',
     1367            ),
     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',
    13171379            ),
    13181380        );
Note: See TracChangeset for help on using the changeset viewer.