Make WordPress Core


Ignore:
Timestamp:
08/11/2021 09:06:31 AM (5 years ago)
Author:
gziolo
Message:

Blocks: Add support for variations in block.json` file

We integrated variations with block types and the corresponding REST API endpoint in #52688. It's a follow-up patch to add missing support to the block.json metadata file when using register_block_type.

Some fields for variations are translatable.Therefore, i18n schema was copied over from Gutenberg: https://github.com/WordPress/gutenberg/blob/trunk/packages/blocks/src/api/i18n-block.json. The accompanying implementation was adapted as translate_settings_using_i18n_schema.

Props: gwwar, swissspidy, schlessera, jorgefilipecosta.
Fixes #53238.

File:
1 edited

Legend:

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

    r51472 r51599  
    4141
    4242    /**
    43      * Structure to hold i18n metadata.
    44      *
    45      * @since 5.8.0
     43     * Container to keep loaded i18n schema for `theme.json`.
     44     *
     45     * @since 5.9.0
    4646     * @var array
    4747     */
    48     private static $theme_json_i18n = null;
     48    private static $i18n_schema = null;
    4949
    5050    /**
     
    6060        $config = array();
    6161        if ( $file_path ) {
    62             $decoded_file = json_decode(
    63                 file_get_contents( $file_path ),
    64                 true
    65             );
    66 
    67             $json_decoding_error = json_last_error();
    68             if ( JSON_ERROR_NONE !== $json_decoding_error ) {
    69                 trigger_error( "Error when decoding a theme.json schema at path $file_path " . json_last_error_msg() );
    70                 return $config;
    71             }
    72 
     62            $decoded_file = wp_json_file_decode( $file_path, array( 'associative' => true ) );
    7363            if ( is_array( $decoded_file ) ) {
    7464                $config = $decoded_file;
     
    7969
    8070    /**
    81      * Converts a tree as in i18n-theme.json into a linear array
    82      * containing metadata to translate a theme.json file.
    83      *
    84      * For example, given this input:
    85      *
    86      *     {
    87      *       "settings": {
    88      *         "*": {
    89      *           "typography": {
    90      *             "fontSizes": [ { "name": "Font size name" } ],
    91      *             "fontStyles": [ { "name": "Font size name" } ]
    92      *           }
    93      *         }
    94      *       }
    95      *     }
    96      *
    97      * will return this output:
    98      *
    99      *     [
    100      *       0 => [
    101      *         'path'    => [ 'settings', '*', 'typography', 'fontSizes' ],
    102      *         'key'     => 'name',
    103      *         'context' => 'Font size name'
    104      *       ],
    105      *       1 => [
    106      *         'path'    => [ 'settings', '*', 'typography', 'fontStyles' ],
    107      *         'key'     => 'name',
    108      *         'context' => 'Font style name'
    109      *       ]
    110      *     ]
    111      *
    112      * @since 5.8.0
    113      *
    114      * @param array $i18n_partial A tree that follows the format of i18n-theme.json.
    115      * @param array $current_path Optional. Keeps track of the path as we walk down the given tree.
    116      *                            Default empty array.
    117      * @return array A linear array containing the paths to translate.
    118      */
    119     private static function extract_paths_to_translate( $i18n_partial, $current_path = array() ) {
    120         $result = array();
    121         foreach ( $i18n_partial as $property => $partial_child ) {
    122             if ( is_numeric( $property ) ) {
    123                 foreach ( $partial_child as $key => $context ) {
    124                     $result[] = array(
    125                         'path'    => $current_path,
    126                         'key'     => $key,
    127                         'context' => $context,
    128                     );
    129                 }
    130                 return $result;
    131             }
    132             $result = array_merge(
    133                 $result,
    134                 self::extract_paths_to_translate( $partial_child, array_merge( $current_path, array( $property ) ) )
    135             );
    136         }
    137         return $result;
    138     }
    139 
    140     /**
    14171     * Returns a data structure used in theme.json translation.
    14272     *
    14373     * @since 5.8.0
     74     * @deprecated 5.9.0
    14475     *
    14576     * @return array An array of theme.json fields that are translatable and the keys that are translatable.
    14677     */
    14778    public static function get_fields_to_translate() {
    148         if ( null === self::$theme_json_i18n ) {
    149             $file_structure        = self::read_json_file( __DIR__ . '/theme-i18n.json' );
    150             self::$theme_json_i18n = self::extract_paths_to_translate( $file_structure );
    151         }
    152         return self::$theme_json_i18n;
    153     }
    154 
    155     /**
    156      * Translates a chunk of the loaded theme.json structure.
    157      *
    158      * @since 5.8.0
    159      *
    160      * @param array  $array_to_translate The chunk of theme.json to translate.
    161      * @param string $key                The key of the field that contains the string to translate.
    162      * @param string $context            The context to apply in the translation call.
    163      * @param string $domain             Text domain. Unique identifier for retrieving translated strings.
    164      * @return array Returns the modified $theme_json chunk.
    165      */
    166     private static function translate_theme_json_chunk( array $array_to_translate, $key, $context, $domain ) {
    167         foreach ( $array_to_translate as $item_key => $item_to_translate ) {
    168             if ( empty( $item_to_translate[ $key ] ) ) {
    169                 continue;
    170             }
    171 
    172             // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain
    173             $array_to_translate[ $item_key ][ $key ] = translate_with_gettext_context( $array_to_translate[ $item_key ][ $key ], $context, $domain );
    174         }
    175 
    176         return $array_to_translate;
     79        _deprecated_function( __METHOD__, '5.9.0' );
     80        return array();
    17781    }
    17882
     
    18993     */
    19094    private static function translate( $theme_json, $domain = 'default' ) {
    191         $fields = self::get_fields_to_translate();
    192         foreach ( $fields as $field ) {
    193             $path    = $field['path'];
    194             $key     = $field['key'];
    195             $context = $field['context'];
    196 
    197             /*
    198              * We need to process the paths that include '*' separately.
    199              * One example of such a path would be:
    200              * [ 'settings', 'blocks', '*', 'color', 'palette' ]
    201              */
    202             $nodes_to_iterate = array_keys( $path, '*', true );
    203             if ( ! empty( $nodes_to_iterate ) ) {
    204                 /*
    205                  * At the moment, we only need to support one '*' in the path, so take it directly.
    206                  * - base will be [ 'settings', 'blocks' ]
    207                  * - data will be [ 'color', 'palette' ]
    208                  */
    209                 $base_path = array_slice( $path, 0, $nodes_to_iterate[0] );
    210                 $data_path = array_slice( $path, $nodes_to_iterate[0] + 1 );
    211                 $base_tree = _wp_array_get( $theme_json, $base_path, array() );
    212                 foreach ( $base_tree as $node_name => $node_data ) {
    213                     $array_to_translate = _wp_array_get( $node_data, $data_path, null );
    214                     if ( is_null( $array_to_translate ) ) {
    215                         continue;
    216                     }
    217 
    218                     // Whole path will be [ 'settings', 'blocks', 'core/paragraph', 'color', 'palette' ].
    219                     $whole_path       = array_merge( $base_path, array( $node_name ), $data_path );
    220                     $translated_array = self::translate_theme_json_chunk( $array_to_translate, $key, $context, $domain );
    221                     _wp_array_set( $theme_json, $whole_path, $translated_array );
    222                 }
    223             } else {
    224                 $array_to_translate = _wp_array_get( $theme_json, $path, null );
    225                 if ( is_null( $array_to_translate ) ) {
    226                     continue;
    227                 }
    228 
    229                 $translated_array = self::translate_theme_json_chunk( $array_to_translate, $key, $context, $domain );
    230                 _wp_array_set( $theme_json, $path, $translated_array );
    231             }
    232         }
    233 
    234         return $theme_json;
     95        if ( null === self::$i18n_schema ) {
     96            $i18n_schema = wp_json_file_decode( __DIR__ . '/theme-i18n.json' );
     97            self::$i18n_schema = null === $i18n_schema ? array() : $i18n_schema;
     98        }
     99
     100        return translate_settings_using_i18n_schema( self::$i18n_schema, $theme_json, $domain );
    235101    }
    236102
     
    366232        self::$theme             = null;
    367233        self::$theme_has_support = null;
    368         self::$theme_json_i18n   = null;
    369234    }
    370235
Note: See TracChangeset for help on using the changeset viewer.