-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Blocks: Add support for variations in block.json file
#1499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
423bb78
549caab
b502e46
6d487f5
b0241ab
3cee73e
b3d33bb
109ae1e
3cf04e4
2c424a6
84781d2
0d0f084
d11f5dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| { | ||
| "title": "block title", | ||
| "description": "block description", | ||
| "keywords": [ "block keyword" ], | ||
| "styles": [ | ||
| { | ||
| "label": "block style label" | ||
| } | ||
| ], | ||
| "variations": [ | ||
| { | ||
| "title": "block variation title", | ||
| "description": "block variation description", | ||
| "keywords": [ "block variation keyword" ] | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,12 +40,12 @@ class WP_Theme_JSON_Resolver { | |
| private static $theme_has_support = null; | ||
|
|
||
| /** | ||
| * Structure to hold i18n metadata. | ||
| * Container to keep loaded i18n schema for `theme.json`. | ||
| * | ||
| * @since 5.8.0 | ||
| * @since 5.9.0 | ||
| * @var array | ||
| */ | ||
| private static $theme_json_i18n = null; | ||
| private static $i18n_schema = null; | ||
|
|
||
| /** | ||
| * Processes a file that adheres to the theme.json schema | ||
|
|
@@ -59,121 +59,25 @@ class WP_Theme_JSON_Resolver { | |
| private static function read_json_file( $file_path ) { | ||
| $config = array(); | ||
| if ( $file_path ) { | ||
| $decoded_file = json_decode( | ||
| file_get_contents( $file_path ), | ||
| true | ||
| ); | ||
|
|
||
| $json_decoding_error = json_last_error(); | ||
| if ( JSON_ERROR_NONE !== $json_decoding_error ) { | ||
| trigger_error( "Error when decoding a theme.json schema at path $file_path " . json_last_error_msg() ); | ||
| return $config; | ||
| } | ||
|
|
||
| $decoded_file = wp_json_file_decode( $file_path, array( 'associative' => true ) ); | ||
| if ( is_array( $decoded_file ) ) { | ||
| $config = $decoded_file; | ||
| } | ||
| } | ||
| return $config; | ||
| } | ||
|
|
||
| /** | ||
| * Converts a tree as in i18n-theme.json into a linear array | ||
| * containing metadata to translate a theme.json file. | ||
| * | ||
| * For example, given this input: | ||
| * | ||
| * { | ||
| * "settings": { | ||
| * "*": { | ||
| * "typography": { | ||
| * "fontSizes": [ { "name": "Font size name" } ], | ||
| * "fontStyles": [ { "name": "Font size name" } ] | ||
| * } | ||
| * } | ||
| * } | ||
| * } | ||
| * | ||
| * will return this output: | ||
| * | ||
| * [ | ||
| * 0 => [ | ||
| * 'path' => [ 'settings', '*', 'typography', 'fontSizes' ], | ||
| * 'key' => 'name', | ||
| * 'context' => 'Font size name' | ||
| * ], | ||
| * 1 => [ | ||
| * 'path' => [ 'settings', '*', 'typography', 'fontStyles' ], | ||
| * 'key' => 'name', | ||
| * 'context' => 'Font style name' | ||
| * ] | ||
| * ] | ||
| * | ||
| * @since 5.8.0 | ||
| * | ||
| * @param array $i18n_partial A tree that follows the format of i18n-theme.json. | ||
| * @param array $current_path Optional. Keeps track of the path as we walk down the given tree. | ||
| * Default empty array. | ||
| * @return array A linear array containing the paths to translate. | ||
| */ | ||
| private static function extract_paths_to_translate( $i18n_partial, $current_path = array() ) { | ||
| $result = array(); | ||
| foreach ( $i18n_partial as $property => $partial_child ) { | ||
| if ( is_numeric( $property ) ) { | ||
| foreach ( $partial_child as $key => $context ) { | ||
| $result[] = array( | ||
| 'path' => $current_path, | ||
| 'key' => $key, | ||
| 'context' => $context, | ||
| ); | ||
| } | ||
| return $result; | ||
| } | ||
| $result = array_merge( | ||
| $result, | ||
| self::extract_paths_to_translate( $partial_child, array_merge( $current_path, array( $property ) ) ) | ||
| ); | ||
| } | ||
| return $result; | ||
| } | ||
|
|
||
| /** | ||
| * Returns a data structure used in theme.json translation. | ||
| * | ||
| * @since 5.8.0 | ||
| * @deprecated 5.9.0 | ||
| * | ||
| * @return array An array of theme.json fields that are translatable and the keys that are translatable. | ||
| */ | ||
| public static function get_fields_to_translate() { | ||
| if ( null === self::$theme_json_i18n ) { | ||
| $file_structure = self::read_json_file( __DIR__ . '/theme-i18n.json' ); | ||
| self::$theme_json_i18n = self::extract_paths_to_translate( $file_structure ); | ||
| } | ||
| return self::$theme_json_i18n; | ||
| } | ||
|
|
||
| /** | ||
| * Translates a chunk of the loaded theme.json structure. | ||
| * | ||
| * @since 5.8.0 | ||
| * | ||
| * @param array $array_to_translate The chunk of theme.json to translate. | ||
| * @param string $key The key of the field that contains the string to translate. | ||
| * @param string $context The context to apply in the translation call. | ||
| * @param string $domain Text domain. Unique identifier for retrieving translated strings. | ||
| * @return array Returns the modified $theme_json chunk. | ||
| */ | ||
| private static function translate_theme_json_chunk( array $array_to_translate, $key, $context, $domain ) { | ||
| foreach ( $array_to_translate as $item_key => $item_to_translate ) { | ||
| if ( empty( $item_to_translate[ $key ] ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain | ||
| $array_to_translate[ $item_key ][ $key ] = translate_with_gettext_context( $array_to_translate[ $item_key ][ $key ], $context, $domain ); | ||
| } | ||
|
|
||
| return $array_to_translate; | ||
| _deprecated_function( __METHOD__, '5.9.0' ); | ||
| return array(); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -188,50 +92,12 @@ private static function translate_theme_json_chunk( array $array_to_translate, $ | |
| * @return array Returns the modified $theme_json_structure. | ||
| */ | ||
| private static function translate( $theme_json, $domain = 'default' ) { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This PR replaces the existing logic to translate @jorgefilipecosta and @nosolosw, I would appreciate your feedback.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested theme.json translation and things are working well 👍 Nice work! We should probably also update plugin code right?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could update the plugin, although it works exactly the same so I consider it a low priority. I'll have to explore what is necessary to bring |
||
| $fields = self::get_fields_to_translate(); | ||
| foreach ( $fields as $field ) { | ||
| $path = $field['path']; | ||
| $key = $field['key']; | ||
| $context = $field['context']; | ||
|
|
||
| /* | ||
| * We need to process the paths that include '*' separately. | ||
| * One example of such a path would be: | ||
| * [ 'settings', 'blocks', '*', 'color', 'palette' ] | ||
| */ | ||
| $nodes_to_iterate = array_keys( $path, '*', true ); | ||
| if ( ! empty( $nodes_to_iterate ) ) { | ||
| /* | ||
| * At the moment, we only need to support one '*' in the path, so take it directly. | ||
| * - base will be [ 'settings', 'blocks' ] | ||
| * - data will be [ 'color', 'palette' ] | ||
| */ | ||
| $base_path = array_slice( $path, 0, $nodes_to_iterate[0] ); | ||
| $data_path = array_slice( $path, $nodes_to_iterate[0] + 1 ); | ||
| $base_tree = _wp_array_get( $theme_json, $base_path, array() ); | ||
| foreach ( $base_tree as $node_name => $node_data ) { | ||
| $array_to_translate = _wp_array_get( $node_data, $data_path, null ); | ||
| if ( is_null( $array_to_translate ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| // Whole path will be [ 'settings', 'blocks', 'core/paragraph', 'color', 'palette' ]. | ||
| $whole_path = array_merge( $base_path, array( $node_name ), $data_path ); | ||
| $translated_array = self::translate_theme_json_chunk( $array_to_translate, $key, $context, $domain ); | ||
| _wp_array_set( $theme_json, $whole_path, $translated_array ); | ||
| } | ||
| } else { | ||
| $array_to_translate = _wp_array_get( $theme_json, $path, null ); | ||
| if ( is_null( $array_to_translate ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| $translated_array = self::translate_theme_json_chunk( $array_to_translate, $key, $context, $domain ); | ||
| _wp_array_set( $theme_json, $path, $translated_array ); | ||
| } | ||
| if ( null === self::$i18n_schema ) { | ||
| $i18n_schema = wp_json_file_decode( __DIR__ . '/theme-i18n.json' ); | ||
| self::$i18n_schema = null === $i18n_schema ? array() : $i18n_schema; | ||
| } | ||
|
|
||
| return $theme_json; | ||
| return translate_settings_using_i18n_schema( self::$i18n_schema, $theme_json, $domain ); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -365,7 +231,6 @@ public static function clean_cached_data() { | |
| self::$core = null; | ||
| self::$theme = null; | ||
| self::$theme_has_support = null; | ||
| self::$theme_json_i18n = null; | ||
| } | ||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.