Skip to content
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

Migrate theme.json v1 to v2 #36155

Merged
merged 11 commits into from
Nov 3, 2021
12 changes: 6 additions & 6 deletions docs/how-to-guides/themes/create-block-theme.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ To enable border styles, add a `border` object under `settings` with the followi
"settings": {
"border": {
"color": true,
"customRadius": true,
"radius": true,
"style": true,
"width": true
}
Expand All @@ -456,7 +456,7 @@ To enable link colors, add a `color` setting and set `link` to true:
"settings": {
"border": {
"color": true,
"customRadius": true,
"radius": true,
"style": true,
"width": true
},
Expand All @@ -475,16 +475,16 @@ To enable padding, margin and custom spacing units, include a setting for spacin
"settings": {
"border": {
"color": true,
"customRadius": true,
"radius": true,
"style": true,
"width": true
},
"color": {
"link": true
},
"spacing": {
"customPadding": true,
"customMargin": true,
"padding": true,
"margin": true,
"units": [ "px", "em", "rem", "vh", "vw" ]
}
}
Expand All @@ -501,7 +501,7 @@ If you want to disable gradients, which are enabled by default, set `gradient` t
"settings": {
"border": {
"color": true,
"customRadius": true,
"radius": true,
"style": true,
"width": true
},
Expand Down
12 changes: 6 additions & 6 deletions docs/how-to-guides/themes/theme-json.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ The settings section has the following structure:
"settings": {
"border": {
"color": false,
"customRadius": false,
"radius": false,
"style": false,
"width": false
},
Expand All @@ -242,19 +242,19 @@ The settings section has the following structure:
},
"spacing": {
"blockGap": null,
"customMargin": false,
"customPadding": false,
"margin": false,
"padding": false,
"units": [ "px", "em", "rem", "vh", "vw" ]
},
"typography": {
"customFontSize": true,
"customLineHeight": false,
"dropCap": true,
"fontFamilies": [],
"fontSizes": [],
"fontStyle": true,
"fontWeight": true,
"letterSpacing": true,
"lineHeight": false,
"textDecoration": true,
"textTransform": true
},
Expand Down Expand Up @@ -286,8 +286,8 @@ To retain backward compatibility, the existing `add_theme_support` declarations

| add_theme_support | theme.json setting |
| --------------------------- | --------------------------------------------------------- |
| `custom-line-height` | Set `typography.customLineHeight` to `true`. |
| `custom-spacing` | Set `spacing.customPadding` to `true`. |
| `custom-line-height` | Set `typography.lineHeight` to `true`. |
| `custom-spacing` | Set `spacing.padding` to `true`. |
| `custom-units` | Provide the list of units via `spacing.units`. |
| `disable-custom-colors` | Set `color.custom` to `false`. |
| `disable-custom-font-sizes` | Set `typography.customFontSize` to `false`. |
Expand Down
54 changes: 31 additions & 23 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ class WP_Theme_JSON_Gutenberg {

const VALID_SETTINGS = array(
'border' => array(
'color' => null,
'customRadius' => null,
'style' => null,
'width' => null,
'color' => null,
'radius' => null,
'style' => null,
'width' => null,
),
'color' => array(
'background' => null,
Expand All @@ -104,22 +104,22 @@ class WP_Theme_JSON_Gutenberg {
'wideSize' => null,
),
'spacing' => array(
'blockGap' => null,
'customMargin' => null,
'customPadding' => null,
'units' => null,
'blockGap' => null,
'margin' => null,
'padding' => null,
'units' => null,
),
'typography' => array(
'customFontSize' => null,
'customLineHeight' => null,
'dropCap' => null,
'fontFamilies' => null,
'fontSizes' => null,
'fontStyle' => null,
'fontWeight' => null,
'letterSpacing' => null,
'textDecoration' => null,
'textTransform' => null,
'customFontSize' => null,
'dropCap' => null,
'fontFamilies' => null,
'fontSizes' => null,
'fontStyle' => null,
'fontWeight' => null,
'letterSpacing' => null,
'lineHeight' => null,
'textDecoration' => null,
'textTransform' => null,
),
);

Expand Down Expand Up @@ -273,7 +273,7 @@ class WP_Theme_JSON_Gutenberg {
'h6' => 'h6',
);

const LATEST_SCHEMA = 1;
const LATEST_SCHEMA = 2;

/**
* Constructor.
Expand Down Expand Up @@ -313,16 +313,24 @@ public function __construct( $theme_json = array(), $origin = 'theme' ) {
* @return array The structure in the last version.
*/
private static function migrate( $theme_json ) {
// Can be removed when the plugin minimum required version is WordPress 5.8.
// This doesn't need to land in WordPress core.
if ( ! isset( $theme_json['version'] ) || 0 === $theme_json['version'] ) {
$theme_json = WP_Theme_JSON_Schema_V0_To_V1::migrate( $theme_json );
}

// Provide backwards compatibility for settings that did not land in 5.8
// and have had their `custom` prefixed removed since.
// Can be removed when the plugin minimum required version is WordPress 5.9.
// This doesn't need to land in WordPress core.
if ( 1 === $theme_json['version'] ) {
$theme_json = WP_Theme_JSON_Schema_V1_Remove_Custom_Prefixes::migrate( $theme_json );
}

if ( 1 === $theme_json['version'] ) {
$theme_json = WP_Theme_JSON_Schema_V1_To_V2::migrate( $theme_json );
}

return $theme_json;
}

Expand Down Expand Up @@ -1086,8 +1094,8 @@ private function get_preset_classes( $setting_nodes, $origins ) {
* }
* },
* 'core/paragraph': {
* 'spacing': {
* 'customPadding': true
* 'typography': {
* 'customFontSize': true
* }
* }
* }
Expand Down Expand Up @@ -1545,7 +1553,7 @@ public static function get_from_editor_settings( $settings ) {
if ( ! isset( $theme_settings['settings']['typography'] ) ) {
$theme_settings['settings']['typography'] = array();
}
$theme_settings['settings']['typography']['customLineHeight'] = $settings['enableCustomLineHeight'];
$theme_settings['settings']['typography']['lineHeight'] = $settings['enableCustomLineHeight'];
}

if ( isset( $settings['enableCustomUnits'] ) ) {
Expand Down Expand Up @@ -1593,7 +1601,7 @@ public static function get_from_editor_settings( $settings ) {
if ( ! isset( $theme_settings['settings']['spacing'] ) ) {
$theme_settings['settings']['spacing'] = array();
}
$theme_settings['settings']['spacing']['customPadding'] = $settings['enableCustomSpacing'];
$theme_settings['settings']['spacing']['padding'] = $settings['enableCustomSpacing'];
}

// Things that didn't land in core yet, so didn't have a setting assigned.
Expand Down
111 changes: 111 additions & 0 deletions lib/class-wp-theme-json-schema-v1-to-v2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
/**
* Class that implements a WP_Theme_JSON_Schema migrator.
*
* @package gutenberg
*/

/**
* Class that implements a migration from a v1 data structure into a v2 one.
*/
class WP_Theme_JSON_Schema_V1_To_V2 implements WP_Theme_JSON_Schema {
Copy link
Member

Choose a reason for hiding this comment

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

I think one day we will need a v2 to v3 migration and v3 to v4...
Having a file "lib/class-wp-theme-json-schema-v1-to-v2.php" and class per migration "WP_Theme_JSON_Schema_V1_To_V2" does not scale well. Files and classes are part of the public API.

Could we have a single migrate class that then has private methods inside per migration we need?

Copy link
Member

Choose a reason for hiding this comment

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

Classes should have _Gutenberg suffix otherwise when we pass the class with the same name to core we are going to have a crash.

/**
* Maps old properties to their new location within the schema's settings.
* This will be applied at both the defaults and individual block levels.
*/
const RENAMED_PATHS = array(
'border.customRadius' => 'border.radius',
'spacing.customMargin' => 'spacing.margin',
'spacing.customPadding' => 'spacing.padding',
'typography.customLineHeight' => 'typography.lineHeight',
);

/**
* Removes the custom prefixes for a few properties
* that were part of v1:
*
* 'border.customRadius' => 'border.radius',
* 'spacing.customMargin' => 'spacing.margin',
* 'spacing.customPadding' => 'spacing.padding',
* 'typography.customLineHeight' => 'typography.lineHeight',
*
* @param array $old Data to migrate.
*
* @return array Data without the custom prefixes.
*/
public static function migrate( $old ) {
// Copy everything.
$new = $old;

// Overwrite the things that changed.
if ( isset( $old['settings'] ) ) {
$new['settings'] = self::process_settings( $old['settings'] );
}

// Set the new version.
$new['version'] = 2;

return $new;
}

/**
* Processes the settings subtree.
*
* @param array $settings Array to process.
*
* @return array The settings in the new format.
*/
private static function process_settings( $settings ) {
$new_settings = $settings;

// Process any renamed/moved paths within default settings.
self::rename_settings( $new_settings );

// Process individual block settings.
if ( isset( $new_settings['blocks'] ) && is_array( $new_settings['blocks'] ) ) {
foreach ( $new_settings['blocks'] as &$block_settings ) {
self::rename_settings( $block_settings );
}
}

return $new_settings;
}

/**
* Processes a settings array, renaming or moving properties according to
* `self::RENAMED_PATHS`.
*
* @param array $settings Reference to settings either defaults or an individual block's.
* @return void
*/
private static function rename_settings( &$settings ) {
foreach ( self::RENAMED_PATHS as $original => $renamed ) {
$original_path = explode( '.', $original );
$renamed_path = explode( '.', $renamed );
$current_value = _wp_array_get( $settings, $original_path, null );

if ( null !== $current_value ) {
gutenberg_experimental_set( $settings, $renamed_path, $current_value );
self::unset_setting_by_path( $settings, $original_path );
}
}
}

/**
* Removes a property from within the provided settings by its path.
*
* @param array $settings Reference to the current settings array.
* @param array $path Path to the property to be removed.
*
* @return void
*/
private static function unset_setting_by_path( &$settings, $path ) {
$tmp_settings = &$settings; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$last_key = array_pop( $path );
foreach ( $path as $key ) {
$tmp_settings = &$tmp_settings[ $key ];
}

unset( $tmp_settings[ $last_key ] );
}
}
12 changes: 6 additions & 6 deletions lib/global-styles.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,16 @@ function_exists( 'gutenberg_is_edit_site_page' ) &&
$settings['disableCustomFontSizes'] = ! $settings['__experimentalFeatures']['typography']['customFontSize'];
unset( $settings['__experimentalFeatures']['typography']['customFontSize'] );
}
if ( isset( $settings['__experimentalFeatures']['typography']['customLineHeight'] ) ) {
$settings['enableCustomLineHeight'] = $settings['__experimentalFeatures']['typography']['customLineHeight'];
unset( $settings['__experimentalFeatures']['typography']['customLineHeight'] );
if ( isset( $settings['__experimentalFeatures']['typography']['lineHeight'] ) ) {
$settings['enableCustomLineHeight'] = $settings['__experimentalFeatures']['typography']['lineHeight'];
unset( $settings['__experimentalFeatures']['typography']['lineHeight'] );
}
if ( isset( $settings['__experimentalFeatures']['spacing']['units'] ) ) {
$settings['enableCustomUnits'] = $settings['__experimentalFeatures']['spacing']['units'];
}
if ( isset( $settings['__experimentalFeatures']['spacing']['customPadding'] ) ) {
$settings['enableCustomSpacing'] = $settings['__experimentalFeatures']['spacing']['customPadding'];
unset( $settings['__experimentalFeatures']['spacing']['customPadding'] );
if ( isset( $settings['__experimentalFeatures']['spacing']['padding'] ) ) {
$settings['enableCustomSpacing'] = $settings['__experimentalFeatures']['spacing']['padding'];
unset( $settings['__experimentalFeatures']['spacing']['padding'] );
}

return $settings;
Expand Down
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/interface-wp-theme-json-schema.php';
require __DIR__ . '/class-wp-theme-json-schema-v0-to-v1.php';
require __DIR__ . '/class-wp-theme-json-schema-v1-remove-custom-prefixes.php';
require __DIR__ . '/class-wp-theme-json-schema-v1-to-v2.php';
require __DIR__ . '/class-wp-theme-json-gutenberg.php';
require __DIR__ . '/class-wp-theme-json-resolver-gutenberg.php';

Expand Down
14 changes: 7 additions & 7 deletions lib/theme.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": 1,
"version": 2,
"settings": {
"color": {
"background": true,
Expand Down Expand Up @@ -178,9 +178,9 @@
"typography": {
"dropCap": true,
"customFontSize": true,
"customLineHeight": false,
"fontStyle": true,
"fontWeight": true,
"lineHeight": false,
"textTransform": true,
"textDecoration": true,
"letterSpacing": true,
Expand Down Expand Up @@ -214,26 +214,26 @@
},
"spacing": {
"blockGap": null,
"customMargin": false,
"customPadding": false,
"margin": false,
"padding": false,
"units": [ "px", "em", "rem", "vh", "vw", "%" ]
},
"border": {
"color": false,
"customRadius": false,
"radius": false,
"style": false,
"width": false
},
"blocks": {
"core/button": {
"border": {
"customRadius": true
"radius": true
}
},
"core/pullquote": {
"border": {
"color": true,
"customRadius": true,
"radius": true,
"style": true,
"width": true
}
Expand Down
Loading