From 9dc03907ee50cf1b736c7f9920bf694d6af4ee57 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 8 Oct 2021 12:24:13 +0100 Subject: [PATCH 1/8] FSE: Allow child theme.json to be merged with parent theme.json --- lib/class-wp-theme-json-resolver-gutenberg.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 7f5eb1f09527d..f7404c3be2866 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -273,7 +273,19 @@ public static function get_theme_data( $theme_support_data = array() ) { if ( null === self::$theme ) { $theme_json_data = self::read_json_file( self::get_file_path_from_theme( 'theme.json' ) ); $theme_json_data = self::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); - self::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); + self::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); + + // If this is a child theme we want to combine the theme.json from the child with the theme.json with the parent. + if ( is_child_theme() ) { + // Get parent theme.json. + $parent_theme_json_data = self::read_json_file( get_template_directory() . '/theme.json' ); + $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); + $parent_theme_json_class_instance = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); + + // Merge the child theme.json into the parent theme.json. + $parent_theme_json_class_instance->merge( self::$theme ); + self::$theme = $parent_theme_json_class_instance; + } } if ( empty( $theme_support_data ) ) { From e297f714d67ccc693edfbbb9afc058dd2a853fcd Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 8 Oct 2021 13:25:59 +0100 Subject: [PATCH 2/8] Update lib/class-wp-theme-json-resolver-gutenberg.php Co-authored-by: Ari Stathopoulos --- lib/class-wp-theme-json-resolver-gutenberg.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index f7404c3be2866..407f452c69d53 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -278,8 +278,8 @@ public static function get_theme_data( $theme_support_data = array() ) { // If this is a child theme we want to combine the theme.json from the child with the theme.json with the parent. if ( is_child_theme() ) { // Get parent theme.json. - $parent_theme_json_data = self::read_json_file( get_template_directory() . '/theme.json' ); - $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); + $parent_theme_json_data = self::read_json_file( get_template_directory() . '/theme.json' ); + $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); $parent_theme_json_class_instance = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); // Merge the child theme.json into the parent theme.json. From 5a1945257229283d07b097983d90889a25e2af7a Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 8 Oct 2021 13:27:01 +0100 Subject: [PATCH 3/8] add a claifying comment --- lib/class-wp-theme-json-resolver-gutenberg.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 407f452c69d53..e7af85ecaddcb 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -283,6 +283,7 @@ public static function get_theme_data( $theme_support_data = array() ) { $parent_theme_json_class_instance = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); // Merge the child theme.json into the parent theme.json. + // The child theme takes precedence over the parent. $parent_theme_json_class_instance->merge( self::$theme ); self::$theme = $parent_theme_json_class_instance; } From d7c53bee152898eaae08a5986599fd3e9bb4563a Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 8 Oct 2021 14:04:37 +0100 Subject: [PATCH 4/8] Update lib/class-wp-theme-json-resolver-gutenberg.php Co-authored-by: George Mamadashvili --- lib/class-wp-theme-json-resolver-gutenberg.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index e7af85ecaddcb..2e6ed4f56477d 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -279,7 +279,7 @@ public static function get_theme_data( $theme_support_data = array() ) { if ( is_child_theme() ) { // Get parent theme.json. $parent_theme_json_data = self::read_json_file( get_template_directory() . '/theme.json' ); - $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); + $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) ); $parent_theme_json_class_instance = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); // Merge the child theme.json into the parent theme.json. From 88d663066af2f528ff55f9e365083a69ad7af68e Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 8 Oct 2021 14:04:42 +0100 Subject: [PATCH 5/8] Update lib/class-wp-theme-json-resolver-gutenberg.php Co-authored-by: George Mamadashvili --- lib/class-wp-theme-json-resolver-gutenberg.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 2e6ed4f56477d..3c3ba96318175 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -276,7 +276,7 @@ public static function get_theme_data( $theme_support_data = array() ) { self::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); // If this is a child theme we want to combine the theme.json from the child with the theme.json with the parent. - if ( is_child_theme() ) { + if ( wp_get_theme()->parent() ) { // Get parent theme.json. $parent_theme_json_data = self::read_json_file( get_template_directory() . '/theme.json' ); $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) ); From 6a6197e3175469ec99bf3b2fb18895b7b14b1e65 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 8 Oct 2021 17:16:55 +0400 Subject: [PATCH 6/8] Fix lint error --- lib/class-wp-theme-json-resolver-gutenberg.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 3c3ba96318175..ad72924f7e318 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -273,7 +273,7 @@ public static function get_theme_data( $theme_support_data = array() ) { if ( null === self::$theme ) { $theme_json_data = self::read_json_file( self::get_file_path_from_theme( 'theme.json' ) ); $theme_json_data = self::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); - self::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); + self::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); // If this is a child theme we want to combine the theme.json from the child with the theme.json with the parent. if ( wp_get_theme()->parent() ) { From 966463be271cbefd41efec35feaf6b7a5b9a73a0 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 15 Oct 2021 12:04:53 +0400 Subject: [PATCH 7/8] Add directory flag to get_file_path_from_theme method Only use get_theme_file_path in theme_has_support check --- ...class-wp-theme-json-resolver-gutenberg.php | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index ad72924f7e318..c4d1dfcf9723c 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -275,17 +275,16 @@ public static function get_theme_data( $theme_support_data = array() ) { $theme_json_data = self::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); self::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); - // If this is a child theme we want to combine the theme.json from the child with the theme.json with the parent. if ( wp_get_theme()->parent() ) { // Get parent theme.json. - $parent_theme_json_data = self::read_json_file( get_template_directory() . '/theme.json' ); - $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) ); - $parent_theme_json_class_instance = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); + $parent_theme_json_data = self::read_json_file( self::get_file_path_from_theme( 'theme.json', true ) ); + $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) ); + $parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); // Merge the child theme.json into the parent theme.json. // The child theme takes precedence over the parent. - $parent_theme_json_class_instance->merge( self::$theme ); - self::$theme = $parent_theme_json_class_instance; + $parent_theme->merge( self::$theme ); + self::$theme = $parent_theme; } } @@ -489,7 +488,7 @@ public static function get_user_custom_post_type_id() { */ public static function theme_has_support() { if ( ! isset( self::$theme_has_support ) ) { - self::$theme_has_support = (bool) self::get_file_path_from_theme( 'theme.json' ); + self::$theme_has_support = is_readable( get_theme_file_path( 'theme.json' ) ); } return self::$theme_has_support; @@ -503,15 +502,14 @@ public static function theme_has_support() { * otherwise returns the whole file path. * * @param string $file_name Name of the file. + * @param bool $template Use template theme directroy. Default: false. * @return string The whole file path or empty if the file doesn't exist. */ - private static function get_file_path_from_theme( $file_name ) { - $located = ''; - $candidate = get_theme_file_path( $file_name ); - if ( is_readable( $candidate ) ) { - $located = $candidate; - } - return $located; + private static function get_file_path_from_theme( $file_name, $template = false ) { + $path = $template ? get_template_directory() : get_stylesheet_directory(); + $candidate = $path . '/' . $file_name; + + return is_readable( $candidate ) ? $candidate : ''; } /** From e53fcb4bdca99d4356f0d2ad9ce3c4a9f901887b Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 15 Oct 2021 15:05:23 +0400 Subject: [PATCH 8/8] Add unit tests for merging --- phpunit/class-wp-theme-json-resolver-test.php | 59 +++++++++++++++++++ phpunit/data/themedir1/fse-child/style.css | 8 +++ phpunit/data/themedir1/fse-child/theme.json | 51 ++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 phpunit/data/themedir1/fse-child/style.css create mode 100644 phpunit/data/themedir1/fse-child/theme.json diff --git a/phpunit/class-wp-theme-json-resolver-test.php b/phpunit/class-wp-theme-json-resolver-test.php index b2441229d3590..b3986d1b9551a 100644 --- a/phpunit/class-wp-theme-json-resolver-test.php +++ b/phpunit/class-wp-theme-json-resolver-test.php @@ -255,4 +255,63 @@ function test_add_theme_supports_are_loaded_for_themes_without_theme_json() { $this->assertSame( $color_palette, $settings['color']['palette']['theme'] ); } + function test_merges_child_theme_json_into_parent_theme_json() { + switch_theme( 'fse-child' ); + + $actual = WP_Theme_JSON_Resolver_Gutenberg::get_theme_data(); + + // Should merge settings. + $this->assertSame( + array( + 'color' => array( + 'palette' => array( + 'theme' => array( + array( + 'slug' => 'light', + 'name' => 'Light', + 'color' => '#f3f4f6', + ), + array( + 'slug' => 'primary', + 'name' => 'Primary', + 'color' => '#3858e9', + ), + array( + 'slug' => 'dark', + 'name' => 'Dark', + 'color' => '#111827', + ), + ), + ), + 'custom' => true, + ), + 'blocks' => array( + 'core/paragraph' => array( + 'color' => array( + 'palette' => array( + 'theme' => array( + array( + 'slug' => 'light', + 'name' => 'Light', + 'color' => '#f3f4f6', + ), + ), + ), + ), + ), + ), + ), + $actual->get_settings() + ); + + $this->assertSame( + $actual->get_custom_templates(), + array( + 'page-home' => array( + 'title' => 'Homepage', + 'postTypes' => array( 'page' ), + ), + ) + ); + } } diff --git a/phpunit/data/themedir1/fse-child/style.css b/phpunit/data/themedir1/fse-child/style.css new file mode 100644 index 0000000000000..ef9406d1d977d --- /dev/null +++ b/phpunit/data/themedir1/fse-child/style.css @@ -0,0 +1,8 @@ +/* +Theme Name: FSE Child Theme +Theme URI: https://wordpress.org/ +Description: For testing purposes only. +Template: fse +Version: 1.0.0 +Text Domain: fse-child +*/ diff --git a/phpunit/data/themedir1/fse-child/theme.json b/phpunit/data/themedir1/fse-child/theme.json new file mode 100644 index 0000000000000..4e3f75c503fe5 --- /dev/null +++ b/phpunit/data/themedir1/fse-child/theme.json @@ -0,0 +1,51 @@ +{ + "version": 1, + "settings": { + "color": { + "palette": [ + { + "slug": "light", + "name": "Light", + "color": "#f3f4f6" + }, + { + "slug": "primary", + "name": "Primary", + "color": "#3858e9" + }, + { + "slug": "dark", + "name": "Dark", + "color": "#111827" + } + ], + "custom": true + }, + "blocks": { + "core/paragraph": { + "color": { + "palette": [ + { + "slug": "light", + "name": "Light", + "color": "#f3f4f6" + } + ] + } + } + } + }, + "customTemplates": [ + { + "name": "page-home", + "title": "Homepage" + } + ], + "templateParts": [ + { + "name": "small-header", + "title": "Small Header", + "area": "header" + } + ] +}