Skip to content

Commit

Permalink
Make child themes inherit parent's style variations. (#46554)
Browse files Browse the repository at this point in the history
* Include parent theme dir in style variation getter.

* Fix mismatched variable names.

* Refactor to static utility function.

* Check for naming collisions via basename.

* Fix linting errors and warnings.

* Rebase trunk.

* Update version since.

* Use _Gutenberg class.

* Add back line break.

* Fix linting errors.

* Refactor to allow parent theme variations to show up when child has no variations.

* Add unit test for resolver class.

* Comment the test.

* Fix lint.

* Rename variations to account for child overwriting parent variation.
  • Loading branch information
jffng authored Jan 18, 2023
1 parent 77aec3d commit da16e42
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 18 deletions.
58 changes: 42 additions & 16 deletions lib/class-wp-theme-json-resolver-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -670,32 +670,58 @@ public static function clean_cached_data() {
}

/**
* Returns the style variations defined by the theme.
* Returns an array of all nested json files within a given directory.
*
* @since 6.0.0
* @since 6.2.0
*
* @param dir $dir The directory to recursively iterate and list files of.
* @return array The merged array.
*/
private static function recursively_iterate_json( $dir ) {
$nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ) );
$nested_json_files = iterator_to_array( new RegexIterator( $nested_files, '/^.+\.json$/i', RecursiveRegexIterator::GET_MATCH ) );
return $nested_json_files;
}

/**
* Returns the style variations defined by the theme (parent and child).
*
* @since 6.2.0 Returns parent theme variations if theme is a child.
*
* @return array
*/
public static function get_style_variations() {
$variations = array();
$base_directory = get_stylesheet_directory() . '/styles';
$variation_files = array();
$variations = array();
$base_directory = get_stylesheet_directory() . '/styles';
$template_directory = get_template_directory() . '/styles';
if ( is_dir( $base_directory ) ) {
$nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory ) );
$nested_html_files = iterator_to_array( new RegexIterator( $nested_files, '/^.+\.json$/i', RecursiveRegexIterator::GET_MATCH ) );
ksort( $nested_html_files );
foreach ( $nested_html_files as $path => $file ) {
$decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) );
if ( is_array( $decoded_file ) ) {
$translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) );
$variation = ( new WP_Theme_JSON_Gutenberg( $translated ) )->get_raw_data();
if ( empty( $variation['title'] ) ) {
$variation['title'] = basename( $path, '.json' );
$variation_files = static::recursively_iterate_json( $base_directory );
}
if ( is_dir( $template_directory ) && $template_directory !== $base_directory ) {
$variation_files_parent = static::recursively_iterate_json( $template_directory );
// If the child and parent variation file basename are the same, only include the child theme's.
foreach ( $variation_files_parent as $parent_path => $parent ) {
foreach ( $variation_files as $child_path => $child ) {
if ( basename( $parent_path ) === basename( $child_path ) ) {
unset( $variation_files_parent[ $parent_path ] );
}
$variations[] = $variation;
}
}
$variation_files = array_merge( $variation_files, $variation_files_parent );
}
ksort( $variation_files );
foreach ( $variation_files as $path => $file ) {
$decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) );
if ( is_array( $decoded_file ) ) {
$translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) );
$variation = ( new WP_Theme_JSON_Gutenberg( $translated ) )->get_raw_data();
if ( empty( $variation['title'] ) ) {
$variation['title'] = basename( $path, '.json' );
}
$variations[] = $variation;
}
}
return $variations;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,30 @@ public function get_theme_item( $request ) {

return $response;
}

/**
* Returns the given theme global styles variations.
*
* @since 6.0.0
* @since 6.2.0 Returns parent theme variations, if they exist.
*
* @param WP_REST_Request $request The request instance.
*
* @return WP_REST_Response|WP_Error
*/
public function get_theme_items( $request ) {
if ( get_stylesheet() !== $request['stylesheet'] ) {
// This endpoint only supports the active or parent theme for now.
return new WP_Error(
sprintf( '%s', $request['template'] ),
__( 'Theme not found.', 'gutenberg' ),
array( 'status' => 404 )
);
}

$variations = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations();
$response = rest_ensure_response( $variations );

return $response;
}
}
66 changes: 66 additions & 0 deletions phpunit/class-wp-theme-json-resolver-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -503,4 +503,70 @@ public function data_get_merged_data_returns_origin() {
);
}


/**
* Test that get_style_variations returns all variations, including parent theme variations if the theme is a child,
* and that the child variation overwrites the parent variation of the same name.
*
* @covers WP_Theme_JSON_Resolver::get_style_variations
**/
public function test_get_style_variations_returns_all_variations() {
// Switch to a child theme.
switch_theme( 'block-theme-child' );
wp_set_current_user( self::$administrator_id );

$actual_settings = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations();
$expected_settings = array(
array(
'version' => 2,
'title' => 'variation-a',
'settings' => array(
'blocks' => array(
'core/paragraph' => array(
'color' => array(
'palette' => array(
'theme' => array(
array(
'slug' => 'dark',
'name' => 'Dark',
'color' => '#010101',
),
),
),
),
),
),
),
),
array(
'version' => 2,
'title' => 'variation-b',
'settings' => array(
'blocks' => array(
'core/post-title' => array(
'color' => array(
'palette' => array(
'theme' => array(
array(
'slug' => 'light',
'name' => 'Light',
'color' => '#f1f1f1',
),
),
),
),
),
),
),
),
);
self::recursive_ksort( $actual_settings );
self::recursive_ksort( $expected_settings );

$this->assertSame(
$expected_settings,
$actual_settings
);
}

}
18 changes: 18 additions & 0 deletions phpunit/data/themedir1/block-theme-child/styles/variation-a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": 2,
"settings": {
"blocks": {
"core/paragraph": {
"color": {
"palette": [
{
"slug": "dark",
"name": "Dark",
"color": "#010101"
}
]
}
}
}
}
}
2 changes: 1 addition & 1 deletion phpunit/data/themedir1/block-theme-child/theme.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": 1,
"version": 2,
"settings": {
"color": {
"palette": [
Expand Down
18 changes: 18 additions & 0 deletions phpunit/data/themedir1/block-theme/styles/variation-a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": 2,
"settings": {
"blocks": {
"core/paragraph": {
"color": {
"palette": [
{
"slug": "light",
"name": "Light",
"color": "#f2f2f2"
}
]
}
}
}
}
}
18 changes: 18 additions & 0 deletions phpunit/data/themedir1/block-theme/styles/variation-b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": 2,
"settings": {
"blocks": {
"core/post-title": {
"color": {
"palette": [
{
"slug": "light",
"name": "Light",
"color": "#f1f1f1"
}
]
}
}
}
}
}
2 changes: 1 addition & 1 deletion phpunit/data/themedir1/block-theme/theme.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": 1,
"version": 2,
"settings": {
"color": {
"palette": [
Expand Down

1 comment on commit da16e42

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in da16e42.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/3946838829
📝 Reported issues:

Please sign in to comment.