diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index 76a7507f27536..a8d9220a7d2bb 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -71,6 +71,86 @@ private static function get_from_file( $file_path ) { return $config; } + /** + * Processes a tree from i18n-theme.json into a liner array + * containing the a translatable path from theme.json and an array + * of properties that are translatable. + * + * @param array $file_structure_partial A part of a theme.json i18n tree. + * @param array $current_path An array with a path on the theme.json i18n tree. + * + * @return array An array of arrays each one containing a translatable path and an array of properties that are translatable. + */ + private static function theme_json_i18_file_structure_to_paths( $file_structure_partial, $current_path = array() ) { + $result = array(); + foreach ( $file_structure_partial as $property => $partial_child ) { + if ( is_numeric( $property ) ) { + return array( + array( + 'path' => $current_path, + 'translatable_keys' => $file_structure_partial, + ), + ); + } + $result = array_merge( + $result, + self::theme_json_i18_file_structure_to_paths( $partial_child, array_merge( $current_path, array( $property ) ) ) + ); + } + return $result; + } + + /** + * Returns a data structure used in theme.json translation. + * + * @return array An array of theme.json paths that are translatable and the keys that are translatable + */ + private static function get_theme_json_i18n() { + static $theme_json_i18n = null; + if ( null === $theme_json_i18n ) { + $file_structure = self::get_from_file( __DIR__ . '/experimental-i18n-theme.json' ); + $theme_json_i18n = self::theme_json_i18_file_structure_to_paths( $file_structure ); + + } + return $theme_json_i18n; + } + + /** + * Translates a theme.json structure. + * + * @param array $theme_json_structure A theme.json structure that is going to be translatable. + * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. + * Default 'default'. + */ + private static function apply_theme_json_translations( &$theme_json_structure, $domain = 'default' ) { + $theme_json_i18n = self::get_theme_json_i18n(); + foreach ( $theme_json_structure as &$context_value ) { + if ( empty( $context_value ) || empty( $context_value['settings'] ) ) { + continue; + } + $settings = &$context_value['settings']; + foreach ( $theme_json_i18n as $theme_json_i18n_value ) { + $path = $theme_json_i18n_value['path']; + $translatable_keys = $theme_json_i18n_value['translatable_keys']; + $array_to_translate = gutenberg_experimental_get( $settings, $path, null ); + if ( null === $array_to_translate ) { + continue; + } + foreach ( $array_to_translate as &$item_to_translate ) { + foreach ( $translatable_keys as $translatable_key ) { + if ( empty( $item_to_translate[ $translatable_key ] ) ) { + continue; + } + // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain + $item_to_translate[ $translatable_key ] = translate( $item_to_translate[ $translatable_key ], $domain ); + // phpcs:enable + } + } + gutenberg_experimental_set( $settings, $path, $array_to_translate ); + } + } + } + /** * Return core's origin config. * @@ -82,6 +162,7 @@ private static function get_core_origin() { } $config = self::get_from_file( __DIR__ . '/experimental-default-theme.json' ); + self::apply_theme_json_translations( $config ); // Start i18n logic to remove when JSON i18 strings are extracted. $default_colors_i18n = array( @@ -186,6 +267,7 @@ private static function get_core_origin() { */ private function get_theme_origin( $theme_support_data = array() ) { $theme_json_data = self::get_from_file( locate_template( 'experimental-theme.json' ) ); + self::apply_theme_json_translations( $theme_json_data, wp_get_theme()->get_stylesheet() ); /* * We want the presets and settings declared in theme.json diff --git a/lib/experimental-i18n-theme.json b/lib/experimental-i18n-theme.json new file mode 100644 index 0000000000000..6d5db8d2f2128 --- /dev/null +++ b/lib/experimental-i18n-theme.json @@ -0,0 +1,30 @@ +{ + "typography": { + "fontSizes": [ + "name" + ], + "fontStyles": [ + "name" + ], + "fontWeights": [ + "name" + ], + "fontFamilies": [ + "name" + ], + "textTransforms": [ + "name" + ], + "textDecorations": [ + "name" + ] + }, + "color": { + "palette": [ + "name" + ], + "gradients": [ + "name" + ] + } +}