Make WordPress Core


Ignore:
Timestamp:
05/31/2024 05:47:23 AM (6 months ago)
Author:
noisysocks
Message:

Block Themes: Add section styling via extended block style variations

Provide users with the ability to style entire sections of a page without
having to tediously reapply the same sets of styles.

This is done by extending block style variations to apply to nested blocks.

See https://github.com/WordPress/gutenberg/pull/57908.

Fixes #61312.
Props aaronrobertshaw, talldanwp, ramonopoly, isabel_brison, andrewserong.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-theme-json.php

    r58245 r58264  
    347347     *              added the `customTemplates` and `templateParts` values.
    348348     * @since 6.3.0 Added the `description` value.
     349     * @since 6.6.0 Added `blockTypes` to support block style variation theme.json partials.
    349350     * @var string[]
    350351     */
    351352    const VALID_TOP_LEVEL_KEYS = array(
     353        'blockTypes',
    352354        'customTemplates',
    353355        'description',
     
    824826     * @since 5.9.0 Added the `$valid_block_names` and `$valid_element_name` parameters.
    825827     * @since 6.3.0 Added the `$valid_variations` parameter.
     828     * @since 6.6.0 Updated schema to allow extended block style variations.
    826829     *
    827830     * @param array $input               Structure to sanitize.
     
    882885        $schema_styles_blocks   = array();
    883886        $schema_settings_blocks = array();
     887
     888        /*
     889         * Generate a schema for blocks.
     890         * - Block styles can contain `elements` & `variations` definitions.
     891         * - Variations definitions cannot be nested.
     892         * - Variations can contain styles for inner `blocks`.
     893         * - Variation inner `blocks` styles can contain `elements`.
     894         *
     895         * As each variation needs a `blocks` schema but further nested
     896         * inner `blocks`, the overall schema will be generated in multiple passes.
     897         */
     898        foreach ( $valid_block_names as $block ) {
     899            $schema_settings_blocks[ $block ]           = static::VALID_SETTINGS;
     900            $schema_styles_blocks[ $block ]             = $styles_non_top_level;
     901            $schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements;
     902        }
     903
     904        $block_style_variation_styles             = static::VALID_STYLES;
     905        $block_style_variation_styles['blocks']   = $schema_styles_blocks;
     906        $block_style_variation_styles['elements'] = $schema_styles_elements;
     907
    884908        foreach ( $valid_block_names as $block ) {
    885909            // Build the schema for each block style variation.
     
    898922            $schema_styles_variations = array();
    899923            if ( ! empty( $style_variation_names ) ) {
    900                 $schema_styles_variations = array_fill_keys( $style_variation_names, $styles_non_top_level );
    901             }
    902 
    903             $schema_settings_blocks[ $block ]             = static::VALID_SETTINGS;
    904             $schema_styles_blocks[ $block ]               = $styles_non_top_level;
    905             $schema_styles_blocks[ $block ]['elements']   = $schema_styles_elements;
     924                $schema_styles_variations = array_fill_keys( $style_variation_names, $block_style_variation_styles );
     925            }
     926
    906927            $schema_styles_blocks[ $block ]['variations'] = $schema_styles_variations;
    907928        }
     
    913934        $schema['settings']['blocks']                     = $schema_settings_blocks;
    914935        $schema['settings']['typography']['fontFamilies'] = static::schema_in_root_and_per_origin( static::FONT_FAMILY_SCHEMA );
     936
     937        /*
     938         * Shared block style variations can be registered from the theme.json data so we can't
     939         * validate them against pre-registered block style variations.
     940         */
     941        $schema['styles']['blocks']['variations'] = null;
    915942
    916943        // Remove anything that's not present in the schema.
     
    10171044     * @since 6.1.0 Added `features` key with block support feature level selectors.
    10181045     * @since 6.3.0 Refactored and stabilized selectors API.
     1046     * @since 6.6.0 Updated to include block style variations from the block styles registry.
    10191047     *
    10201048     * @return array Block metadata.
    10211049     */
    10221050    protected static function get_blocks_metadata() {
    1023         $registry = WP_Block_Type_Registry::get_instance();
    1024         $blocks   = $registry->get_all_registered();
     1051        $registry       = WP_Block_Type_Registry::get_instance();
     1052        $blocks         = $registry->get_all_registered();
     1053        $style_registry = WP_Block_Styles_Registry::get_instance();
    10251054
    10261055        // Is there metadata for all currently registered blocks?
    10271056        $blocks = array_diff_key( $blocks, static::$blocks_metadata );
    10281057        if ( empty( $blocks ) ) {
     1058            /*
     1059             * New block styles may have been registered within WP_Block_Styles_Registry.
     1060             * Update block metadata for any new block style variations.
     1061             */
     1062            $registered_styles = $style_registry->get_all_registered();
     1063            foreach ( static::$blocks_metadata as $block_name => $block_metadata ) {
     1064                if ( ! empty( $registered_styles[ $block_name ] ) ) {
     1065                    $style_selectors = $block_metadata['styleVariations'] ?? array();
     1066
     1067                    foreach ( $registered_styles[ $block_name ] as $block_style ) {
     1068                        if ( ! isset( $style_selectors[ $block_style['name'] ] ) ) {
     1069                            $style_selectors[ $block_style['name'] ] = static::get_block_style_variation_selector( $block_style['name'], $block_metadata['selector'] );
     1070                        }
     1071                    }
     1072
     1073                    static::$blocks_metadata[ $block_name ]['styleVariations'] = $style_selectors;
     1074                }
     1075            }
    10291076            return static::$blocks_metadata;
    10301077        }
     
    10611108
    10621109            // If the block has style variations, append their selectors to the block metadata.
     1110            $style_selectors = array();
    10631111            if ( ! empty( $block_type->styles ) ) {
    1064                 $style_selectors = array();
    10651112                foreach ( $block_type->styles as $style ) {
    10661113                    $style_selectors[ $style['name'] ] = static::get_block_style_variation_selector( $style['name'], static::$blocks_metadata[ $block_name ]['selector'] );
    10671114                }
     1115            }
     1116
     1117            // Block style variations can be registered through the WP_Block_Styles_Registry as well as block.json.
     1118            $registered_styles = $style_registry->get_registered_styles_for_block( $block_name );
     1119            foreach ( $registered_styles as $style ) {
     1120                $style_selectors[ $style['name'] ] = static::get_block_style_variation_selector( $style['name'], static::$blocks_metadata[ $block_name ]['selector'] );
     1121            }
     1122
     1123            if ( ! empty( $style_selectors ) ) {
    10681124                static::$blocks_metadata[ $block_name ]['styleVariations'] = $style_selectors;
    10691125            }
     
    11591215     * @since 5.9.0 Removed the `$type` parameter, added the `$types` and `$origins` parameters.
    11601216     * @since 6.3.0 Add fallback layout styles for Post Template when block gap support isn't available.
     1217     * @since 6.6.0 Added `skip_root_layout_styles` option to omit layout styles if desired.
    11611218     *
    11621219     * @param string[] $types   Types of styles to load. Will load all by default. It accepts:
     
    11661223     * @param string[] $origins A list of origins to include. By default it includes VALID_ORIGINS.
    11671224     * @param array    $options An array of options for now used for internal purposes only (may change without notice).
    1168      *                          The options currently supported are 'scope' that makes sure all style are scoped to a
    1169      *                          given selector, and root_selector which overwrites and forces a given selector to be
    1170      *                          used on the root node.
     1225     *                       The options currently supported are:
     1226     *                       - 'scope' that makes sure all style are scoped to a given selector
     1227     *                       - `root_selector` which overwrites and forces a given selector to be used on the root node
     1228     *                       - `skip_root_layout_styles` which omits root layout styles from the generated stylesheet.
    11711229     * @return string The resulting stylesheet.
    11721230     */
     
    12211279
    12221280        if ( in_array( 'styles', $types, true ) ) {
    1223             if ( false !== $root_style_key ) {
     1281            if ( false !== $root_style_key && empty( $options['skip_root_layout_styles'] ) ) {
    12241282                $stylesheet .= $this->get_root_layout_rules( $style_nodes[ $root_style_key ]['selector'], $style_nodes[ $root_style_key ] );
    12251283            }
     
    31153173     * @since 5.9.0
    31163174     * @since 6.3.2 Preserves global styles block variations when securing styles.
     3175     * @since 6.6.0 Updated to allow variation element styles.
    31173176     *
    31183177     * @param array $theme_json Structure to sanitize.
     
    31763235
    31773236                    $variation_output = static::remove_insecure_styles( $variation_input );
     3237
     3238                    // Process a variation's elements and element pseudo selector styles.
     3239                    if ( isset( $variation_input['elements'] ) ) {
     3240                        foreach ( $valid_element_names as $element_name ) {
     3241                            $element_input = $variation_input['elements'][ $element_name ] ?? null;
     3242                            if ( $element_input ) {
     3243                                $element_output = static::remove_insecure_styles( $element_input );
     3244
     3245                                if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) {
     3246                                    foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) {
     3247                                        if ( isset( $element_input[ $pseudo_selector ] ) ) {
     3248                                            $element_output[ $pseudo_selector ] = static::remove_insecure_styles( $element_input[ $pseudo_selector ] );
     3249                                        }
     3250                                    }
     3251                                }
     3252
     3253                                if ( ! empty( $element_output ) ) {
     3254                                    _wp_array_set( $variation_output, array( 'elements', $element_name ), $element_output );
     3255                                }
     3256                            }
     3257                        }
     3258                    }
     3259
    31783260                    if ( ! empty( $variation_output ) ) {
    31793261                        _wp_array_set( $sanitized, $variation['path'], $variation_output );
Note: See TracChangeset for help on using the changeset viewer.