Make WordPress Core

Changeset 58466

Timestamp:
06/24/2024 08:49:52 AM (5 weeks ago)
Author:
oandregal
Message:

Section styles: improve performance and conceptual consistency.

These changes involve:

  • Move shared variation definitions from styles.blocks.variations to styles.variations
  • Remove blockTypes from styles.variations.
  • Do not register shared variations from theme style variation or primary theme.json files.
  • Move the merging of theme.json data into the WP_Theme_JSON_Resolver and WP_Theme_JSON classes.

These changes improve performance and are more future-proof API wise.
See conversation at https://github.com/WordPress/gutenberg/issues/62686

Props aaronrobertshaw, oandregal, andrewserong, joemcgill, talldanwp, andrewserong, ramonopoly, richtabor, youknowriad.

See #61312, #61451.

Location:
trunk
Files:
10 edited

Legend:

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

    r58429 r58466  
    214214
    215215/**
    216  * Collects block style variation data for merging with theme.json data.
    217  *
    218  * @since 6.6.0
    219  * @access private
    220  *
    221  * @param array $variations Shared block style variations.
    222  *
    223  * @return array Block variations data to be merged under `styles.blocks`.
    224  */
    225 function wp_resolve_block_style_variations( $variations ) {
    226     $variations_data = array();
    227 
    228     if ( empty( $variations ) ) {
    229         return $variations_data;
    230     }
    231 
    232     $have_named_variations = ! wp_is_numeric_array( $variations );
    233 
    234     foreach ( $variations as $key => $variation ) {
    235         $supported_blocks = $variation['blockTypes'] ?? array();
    236 
    237         /*
    238          * Standalone theme.json partial files for block style variations
    239          * will have their styles under a top-level property by the same name.
    240          * Variations defined within an existing theme.json or theme style
    241          * variation will themselves already be the required styles data.
    242          */
    243         $variation_data = $variation['styles'] ?? $variation;
    244 
    245         if ( empty( $variation_data ) ) {
    246             continue;
    247         }
    248 
    249         /*
    250          * Block style variations read in via standalone theme.json partials
    251          * need to have their name set to the kebab case version of their title.
    252          */
    253         $variation_name = $have_named_variations ? $key : ( $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ) );
    254 
    255         foreach ( $supported_blocks as $block_type ) {
    256             // Add block style variation data under current block type.
    257             $path = array( $block_type, 'variations', $variation_name );
    258             _wp_array_set( $variations_data, $path, $variation_data );
    259         }
    260     }
    261 
    262     return $variations_data;
    263 }
    264 
    265 /**
    266  * Merges variations data with existing theme.json data ensuring that the
    267  * current theme.json data values take precedence.
    268  *
    269  * @since 6.6.0
    270  * @access private
    271  *
    272  * @param array              $variations_data Block style variations data keyed by block type.
    273  * @param WP_Theme_JSON_Data $theme_json      Current theme.json data.
    274  * @param string             $origin          Origin for the theme.json data.
    275  *
    276  * @return WP_Theme_JSON The merged theme.json data.
    277  */
    278 function wp_merge_block_style_variations_data( $variations_data, $theme_json, $origin = 'theme' ) {
    279     if ( empty( $variations_data ) ) {
    280         return $theme_json;
    281     }
    282 
    283     $variations_theme_json_data = array(
    284         'version' => WP_Theme_JSON::LATEST_SCHEMA,
    285         'styles'  => array( 'blocks' => $variations_data ),
    286     );
    287 
    288     $variations_theme_json = new WP_Theme_JSON_Data( $variations_theme_json_data, $origin );
    289 
    290     /*
    291      * Merge the current theme.json data over shared variation data so that
    292      * any explicit per block variation values take precedence.
    293      */
    294     return $variations_theme_json->update_with( $theme_json->get_data() );
    295 }
    296 
    297 /**
    298  * Merges any shared block style variation definitions from a theme style
    299  * variation into their appropriate block type within theme json styles. Any
    300  * custom user selections already made will take precedence over the shared
    301  * style variation value.
    302  *
    303  * @since 6.6.0
    304  * @access private
    305  *
    306  * @param WP_Theme_JSON_Data $theme_json Current theme.json data.
    307  *
    308  * @return WP_Theme_JSON_Data
    309  */
    310 function wp_resolve_block_style_variations_from_theme_style_variation( $theme_json ) {
    311     $theme_json_data   = $theme_json->get_data();
    312     $shared_variations = $theme_json_data['styles']['blocks']['variations'] ?? array();
    313     $variations_data   = wp_resolve_block_style_variations( $shared_variations );
    314 
    315     return wp_merge_block_style_variations_data( $variations_data, $theme_json, 'user' );
    316 }
    317 
    318 /**
    319  * Merges block style variation data sourced from standalone partial
    320  * theme.json files.
    321  *
    322  * @since 6.6.0
    323  * @access private
    324  *
    325  * @param WP_Theme_JSON_Data $theme_json Current theme.json data.
    326  *
    327  * @return WP_Theme_JSON_Data
    328  */
    329 function wp_resolve_block_style_variations_from_theme_json_partials( $theme_json ) {
    330     $block_style_variations = WP_Theme_JSON_Resolver::get_style_variations( 'block' );
    331     $variations_data        = wp_resolve_block_style_variations( $block_style_variations );
    332 
    333     return wp_merge_block_style_variations_data( $variations_data, $theme_json );
    334 }
    335 
    336 /**
    337  * Merges shared block style variations registered within the
    338  * `styles.blocks.variations` property of the primary theme.json file.
    339  *
    340  * @since 6.6.0
    341  * @access private
    342  *
    343  * @param WP_Theme_JSON_Data $theme_json Current theme.json data.
    344  *
    345  * @return WP_Theme_JSON_Data
    346  */
    347 function wp_resolve_block_style_variations_from_primary_theme_json( $theme_json ) {
    348     $theme_json_data        = $theme_json->get_data();
    349     $block_style_variations = $theme_json_data['styles']['blocks']['variations'] ?? array();
    350     $variations_data        = wp_resolve_block_style_variations( $block_style_variations );
    351 
    352     return wp_merge_block_style_variations_data( $variations_data, $theme_json );
    353 }
    354 
    355 /**
    356  * Merges block style variations registered via the block styles registry with a
    357  * style object, under their appropriate block types within theme.json styles.
    358  * Any variation values defined within the theme.json specific to a block type
    359  * will take precedence over these shared definitions.
    360  *
    361  * @since 6.6.0
    362  * @access private
    363  *
    364  * @param WP_Theme_JSON_Data $theme_json Current theme.json data.
    365  *
    366  * @return WP_Theme_JSON_Data
    367  */
    368 function wp_resolve_block_style_variations_from_styles_registry( $theme_json ) {
    369     $registry        = WP_Block_Styles_Registry::get_instance();
    370     $styles          = $registry->get_all_registered();
    371     $variations_data = array();
    372 
    373     foreach ( $styles as $block_type => $variations ) {
    374         foreach ( $variations as $variation_name => $variation ) {
    375             if ( ! empty( $variation['style_data'] ) ) {
    376                 $path = array( $block_type, 'variations', $variation_name );
    377                 _wp_array_set( $variations_data, $path, $variation['style_data'] );
    378             }
    379         }
    380     }
    381 
    382     return wp_merge_block_style_variations_data( $variations_data, $theme_json );
    383 }
    384 
    385 /**
    386216 * Enqueues styles for block style variations.
    387217 *
     
    400230add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_style_variation_styles', 1 );
    401231
    402 // Resolve block style variations from all their potential sources. The order here is deliberate.
    403 add_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_primary_theme_json', 10, 1 );
    404 add_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_theme_json_partials', 10, 1 );
    405 add_filter( 'wp_theme_json_data_theme', 'wp_resolve_block_style_variations_from_styles_registry', 10, 1 );
    406 
    407 add_filter( 'wp_theme_json_data_user', 'wp_resolve_block_style_variations_from_theme_style_variation', 10, 1 );
    408 
    409 /**
    410  * Registers any block style variations contained within the provided
    411  * theme.json data.
     232/**
     233 * Registers block style variations read in from theme.json partials.
    412234 *
    413235 * @since 6.6.0
     
    416238 * @param array $variations Shared block style variations.
    417239 */
    418 function wp_register_block_style_variations_from_theme_json_data( $variations ) {
     240function wp_register_block_style_variations_from_theme_json_( $variations ) {
    419241    if ( empty( $variations ) ) {
    420         return $variations;
    421     }
    422 
    423     $registry              = WP_Block_Styles_Registry::get_instance();
    424     $have_named_variations = ! wp_is_numeric_array( $variations );
    425 
    426     foreach ( $variations as $key => $variation ) {
    427         $supported_blocks = $variation['blockTypes'] ?? array();
    428 
    429         /*
    430          * Standalone theme.json partial files for block style variations
    431          * will have their styles under a top-level property by the same name.
    432          * Variations defined within an existing theme.json or theme style
    433          * variation will themselves already be the required styles data.
    434          */
    435         $variation_data = $variation['styles'] ?? $variation;
    436 
    437         if ( empty( $variation_data ) ) {
     242        return;
     243    }
     244
     245    $registry = WP_Block_Styles_Registry::get_instance();
     246
     247    foreach ( $variations as $variation ) {
     248        if ( empty( $variation['blockTypes'] ) || empty( $variation['styles'] ) ) {
    438249            continue;
    439250        }
    440251
    441         /*
    442          * Block style variations read in via standalone theme.json partials
    443          * need to have their name set to the kebab case version of their title.
    444          */
    445         $variation_name  = $have_named_variations ? $key : ( $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ) );
     252        $variation_name  = $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] );
    446253        $variation_label = $variation['title'] ?? $variation_name;
    447254
    448         foreach ( $supported_blocks as $block_type ) {
     255        foreach ( $ as $block_type ) {
    449256            $registered_styles = $registry->get_registered_styles_for_block( $block_type );
    450257
  • trunk/src/wp-includes/class-wp-theme-json-resolver.php

    r58443 r58466  
    232232     * @since 6.0.0 Added an `$options` parameter to allow the theme data to be returned without theme supports.
    233233     * @since 6.6.0 Add support for 'default-font-sizes' and 'default-spacing-sizes' theme supports.
    234      *              Register the block style variations coming from the partials and the theme.json.
     234     *              .
    235235     *
    236236     * @param array $deprecated Deprecated. Not used.
     
    259259            }
    260260
    261             // Register variations defined by the theme.
    262             $variations = $theme_json_data['styles']['blocks']['variations'] ?? array();
    263             wp_register_block_style_variations_from_theme_json_data( $variations );
    264 
    265             // Register variations defined by theme partials (theme.json files in the styles directory).
     261            /*
     262             * Register variations defined by theme partials (theme.json files in the styles directory).
     263             * This is required so the variations pass sanitization of theme.json data.
     264             */
    266265            $variations = static::get_style_variations( 'block' );
    267             wp_register_block_style_variations_from_theme_json_data( $variations );
     266            wp_register_block_style_variations_from_theme_json_partials( $variations );
     267
     268            /*
     269             * Source variations from the block registry and block style variation files. Then, merge them into the existing theme.json data.
     270             *
     271             * In case the same style properties are defined in several sources, this is how we should resolve the values,
     272             * from higher to lower priority:
     273             *
     274             * - styles.blocks.blockType.variations from theme.json
     275             * - styles.variations from theme.json
     276             * - variations from block style variation files
     277             * - variations from block styles registry
     278             *
     279             * See test_add_registered_block_styles_to_theme_data and test_unwraps_block_style_variations.
     280             *
     281             */
     282            $theme_json_data = static::inject_variations_from_block_style_variation_files( $theme_json_data, $variations );
     283            $theme_json_data = static::inject_variations_from_block_styles_registry( $theme_json_data );
    268284
    269285            /**
     
    580596                $config = $decoded_data;
    581597            }
    582 
    583             // Register variations defined by the user.
    584             $variations = $config['styles']['blocks']['variations'] ?? array();
    585             wp_register_block_style_variations_from_theme_json_data( $variations );
    586598        }
    587599
     
    886898     * @since 6.6.0
    887899     *
    888      * @param WP_Theme_JSON  $theme_json A theme json instance.
     900     * @param WP_Theme_JSON $theme_json A theme json instance.
    889901     * @return WP_Theme_JSON Theme merged with resolved paths, if any found.
    890902     */
     
    908920        return $theme_json;
    909921    }
     922
     923
     924
     925
     926
     927
     928
     929
     930
     931
     932
     933
     934
     935
     936
     937
     938
     939
     940
     941
     942
     943
     944
     945
     946
     947
     948
     949
     950
     951
     952
     953
     954
     955
     956
     957
     958
     959
     960
     961
     962
     963
     964
     965
     966
     967
     968
     969
     970
     971
     972
     973
     974
     975
     976
     977
     978
     979
     980
     981
     982
     983
     984
     985
     986
     987
     988
     989
     990
     991
     992
     993
     994
     995
     996
     997
     998
     999
     1000
     1001
    9101002}
  • trunk/src/wp-includes/class-wp-theme-json.php

    r58444 r58466  
    744744     *
    745745     * @since 5.8.0
    746      * @since 6.6.0 Key spacingScale by origin, and Pre-generate the
    747      *              spacingSizes from spacingScale.
     746     * @since 6.6.0 Key spacingScale by origin, and Pre-generate the
     747     *              .
    748748     *
    749749     * @param array  $theme_json A structure that follows the theme.json schema.
     
    760760        $valid_element_names = array_keys( static::ELEMENTS );
    761761        $valid_variations    = static::get_valid_block_style_variations();
     762
    762763        $this->theme_json    = static::sanitize( $this->theme_json, $valid_block_names, $valid_element_names, $valid_variations );
    763764        $this->theme_json    = static::maybe_opt_in_into_settings( $this->theme_json );
     
    801802            _wp_array_set( $this->theme_json, $sizes_path, $merged_spacing_sizes );
    802803        }
     804
     805
     806
     807
     808
     809
     810
     811
     812
     813
     814
     815
     816
     817
     818
     819
     820
     821
     822
     823
     824
     825
     826
     827
     828
     829
     830
     831
     832
     833
     834
     835
     836
     837
     838
     839
     840
     841
     842
     843
     844
     845
     846
     847
     848
     849
     850
     851
     852
     853
     854
     855
     856
     857
     858
     859
     860
     861
     862
     863
     864
     865
     866
     867
     868
     869
     870
    803871    }
    804872
     
    9671035        $schema['settings']['blocks']                     = $schema_settings_blocks;
    9681036        $schema['settings']['typography']['fontFamilies'] = static::schema_in_root_and_per_origin( static::FONT_FAMILY_SCHEMA );
    969 
    970         /*
    971          * Shared block style variations can be registered from the theme.json data so we can't
    972          * validate them against pre-registered block style variations.
    973          */
    974         $schema['styles']['blocks']['variations'] = null;
    9751037
    9761038        // Remove anything that's not present in the schema.
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php

    r58429 r58466  
    266266            }
    267267
    268             // Register theme-defined variations.
    269             WP_Theme_JSON_Resolver::get_theme_data();
    270 
    271             // Register user-defined variations.
    272             if ( ! empty( $config['styles']['blocks']['variations'] ) ) {
    273                 wp_register_block_style_variations_from_theme_json_data( $config['styles']['blocks']['variations'] );
    274             }
     268            // Register theme-defined variations e.g. from block style variation partials under `/styles`.
     269            $variations = WP_Theme_JSON_Resolver::get_style_variations( 'block' );
     270            wp_register_block_style_variations_from_theme_json_partials( $variations );
    275271
    276272            if ( isset( $request['settings'] ) ) {
     
    636632
    637633        $response   = array();
     634
     635
     636
     637
     638
    638639        $variations = WP_Theme_JSON_Resolver::get_style_variations();
    639 
    640640        foreach ( $variations as $variation ) {
    641641            $variation_theme_json = new WP_Theme_JSON( $variation );
  • trunk/src/wp-includes/theme-i18n.json

    r58412 r58466  
    8181        }
    8282    },
    83     "styles": {
    84         "blocks": {
    85             "variations": {
    86                 "*": {
    87                     "title": "Style variation name"
    88                 }
    89             }
    90         }
    91     },
    9283    "customTemplates": [
    9384        {
  • trunk/tests/phpunit/data/themedir1/block-theme-child-with-block-style-variations/theme.json

    r58264 r58466  
    11{
    22    "$schema": "https://schemas.wp.org/trunk/theme.json",
    3     "version": 3
     3    "version": 3,
     4    "styles": {
     5        "variations": {
     6            "outline": {
     7                "color": {
     8                    "background": "green",
     9                    "text": "white"
     10                }
     11            },
     12            "block-style-variation-a": {
     13                "color": {
     14                    "background": "darkseagreen"
     15                },
     16                "typography": {
     17                    "fontSize": "2em",
     18                    "lineHeight": "1.4em"
     19                }
     20            }
     21        },
     22        "blocks": {
     23            "core/button": {
     24                "variations": {
     25                    "outline": {
     26                        "color": {
     27                            "background": "red"
     28                        }
     29                    }
     30                }
     31            },
     32            "core/media-text": {
     33                "variations": {
     34                    "block-style-variation-a": {
     35                        "color": {
     36                            "background": "blue"
     37                        },
     38                        "typography": {
     39                            "fontSize": "1.5em"
     40                        }
     41                    }
     42                }
     43            },
     44            "core/heading": {
     45                "variations": {
     46                    "block-style-variation-b": {
     47                        "typography": {
     48                            "fontSize": "3em"
     49                        }
     50                    }
     51                }
     52            }
     53        }
     54    }
    455}
  • trunk/tests/phpunit/tests/block-supports/block-style-variations.php

    r58429 r58466  
    6363     * @ticket 61312
    6464     * @ticket 61440
     65
    6566     */
    6667    public function test_add_registered_block_styles_to_theme_data() {
    6768        switch_theme( 'block-theme' );
    68 
    69         // Register theme-defined variations.
    70         WP_Theme_JSON_Resolver::get_theme_data();
    71         // Register user-defined variations.
    72         WP_Theme_JSON_Resolver::get_user_data();
    7369
    7470        $variation_styles_data = array(
     
    126122        $expected     = array(
    127123            'variations' => array(
    128                 // @ticket 61440
    129                 'WithSlug'                => array(
    130                     'color' => array(
    131                         'background' => 'aliceblue',
    132                         'text'       => 'midnightblue',
    133                     ),
    134                 ),
    135                 'my-variation'            => $variation_styles_data,
    136124
    137125                /*
     
    152140                    ),
    153141                ),
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
    154154            ),
    155155        );
     
    158158        unregister_block_style( 'core/group', 'WithSlug' );
    159159
    160         $this->assertSameSetsWithIndex( $expected, $group_styles );
     160        $this->assertSameSetsWithIndex( $expected, $group_styles );
    161161    }
    162162}
  • trunk/tests/phpunit/tests/rest-api/rest-global-styles-controller.php

    r58394 r58466  
    610610     * @covers WP_REST_Global_Styles_Controller_Gutenberg::update_item
    611611     * @ticket 61312
     612
    612613     */
    613614    public function test_update_item_with_custom_block_style_variations() {
     
    616617            grant_super_admin( self::$admin_id );
    617618        }
     619
     620
     621
     622
     623
     624
     625
     626
     627
     628
     629
     630
    618631
    619632        $group_variations = array(
     
    630643            array(
    631644                'styles' => array(
    632                     'blocks' => array(
    633                         'variations' => array(
    634                             'fromThemeStyleVariation' => array(
    635                                 'blockTypes' => array( 'core/group', 'core/columns' ),
    636                                 'color'      => array(
    637                                     'background' => '#000000',
    638                                     'text'       => '#ffffff',
    639                                 ),
     645                    'variations' => array(
     646                        'fromThemeStyleVariation' => array(
     647                            'blockTypes' => array( 'core/group', 'core/columns' ),
     648                            'color'      => array(
     649                                'background' => '#000000',
     650                                'text'       => '#ffffff',
    640651                            ),
    641652                        ),
     653
     654
    642655                        'core/group' => array(
    643656                            'variations' => $group_variations,
  • trunk/tests/phpunit/tests/theme/wpThemeJson.php

    r58444 r58466  
    39323932
    39333933    /**
     3934
     3935
     3936
     3937
     3938
     3939
     3940
     3941
     3942
     3943
     3944
     3945
     3946
     3947
     3948
     3949
     3950
     3951
     3952
     3953
     3954
     3955
     3956
     3957
     3958
     3959
     3960
     3961
     3962
     3963
     3964
     3965
     3966
     3967
     3968
     3969
     3970
     3971
     3972
     3973
     3974
     3975
     3976
     3977
     3978
     3979
     3980
     3981
     3982
     3983
     3984
     3985
     3986
     3987
     3988
     3989
     3990
     3991
     3992
     3993
     3994
     3995
     3996
     3997
     3998
     3999
     4000
     4001
     4002
     4003
     4004
     4005
     4006
     4007
     4008
     4009
     4010
     4011
     4012
     4013
     4014
     4015
     4016
     4017
     4018
     4019
    39344020     * @ticket 57583
    39354021     *
  • trunk/tests/phpunit/tests/theme/wpThemeJsonResolver.php

    r58413 r58466  
    13221322        $this->assertSame( $expected_data, $actual );
    13231323    }
     1324
     1325
     1326
     1327
     1328
     1329
     1330
     1331
     1332
     1333
     1334
     1335
     1336
     1337
     1338
     1339
     1340
     1341
     1342
     1343
     1344
     1345
     1346
     1347
     1348
     1349
     1350
     1351
     1352
     1353
     1354
     1355
     1356
     1357
     1358
     1359
     1360
     1361
     1362
     1363
     1364
     1365
     1366
     1367
     1368
     1369
     1370
     1371
     1372
     1373
     1374
     1375
     1376
     1377
     1378
     1379
     1380
     1381
     1382
     1383
     1384
     1385
     1386
     1387
     1388
     1389
     1390
     1391
     1392
     1393
     1394
     1395
     1396
     1397
     1398
     1399
     1400
     1401
     1402
     1403
     1404
     1405
     1406
     1407
     1408
     1409
     1410
     1411
     1412
     1413
     1414
    13241415}
Note: See TracChangeset for help on using the changeset viewer.