Skip to content

Commit

Permalink
Editor: Add theme.json v3 migrations.
Browse files Browse the repository at this point in the history
See WordPress/wordpress-develop#6616.
See also the original Gutenberg PRs:
* WordPress/gutenberg#58409
* WordPress/gutenberg#61328
* WordPress/gutenberg#61842
* WordPress/gutenberg#62199
* WordPress/gutenberg#62252

Fixes #61282.

Props ajlende, talldanwp, ramonopoly, ellatrix.


Built from https://develop.svn.wordpress.org/trunk@58328


git-svn-id: http://core.svn.wordpress.org/trunk@57785 1a063a9b-81f0-0310-95a4-ce76da25c4cd
  • Loading branch information
ellatrix committed Jun 4, 2024
1 parent 70d2443 commit 5b9f383
Show file tree
Hide file tree
Showing 10 changed files with 384 additions and 67 deletions.
6 changes: 6 additions & 0 deletions wp-includes/block-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ function get_block_editor_theme_styles() {
* Returns the classic theme supports settings for block editor.
*
* @since 6.2.0
* @since 6.6.0 Add support for 'editor-spacing-sizes' theme support.
*
* @return array The classic theme supports settings.
*/
Expand Down Expand Up @@ -844,5 +845,10 @@ function get_classic_theme_supports_block_editor_settings() {
$theme_settings['gradients'] = $gradient_presets;
}

$spacing_sizes = current( (array) get_theme_support( 'editor-spacing-sizes' ) );
if ( false !== $spacing_sizes ) {
$theme_settings['spacingSizes'] = $spacing_sizes;
}

return $theme_settings;
}
2 changes: 1 addition & 1 deletion wp-includes/class-wp-theme-json-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class WP_Theme_JSON_Data {
* @param array $data Array following the theme.json specification.
* @param string $origin The origin of the data: default, theme, user.
*/
public function __construct( $data = array(), $origin = 'theme' ) {
public function __construct( $data = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA ), $origin = 'theme' ) {
$this->origin = $origin;
$this->theme_json = new WP_Theme_JSON( $data, $this->origin );
}
Expand Down
45 changes: 37 additions & 8 deletions wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ protected static function has_same_registered_blocks( $origin ) {
* @since 5.8.0
* @since 5.9.0 Theme supports have been inlined and the `$theme_support_data` argument removed.
* @since 6.0.0 Added an `$options` parameter to allow the theme data to be returned without theme supports.
* @since 6.6.0 Add support for 'default-font-sizes' and 'default-spacing-sizes' theme supports.
*
* @param array $deprecated Deprecated. Not used.
* @param array $options {
Expand All @@ -243,7 +244,7 @@ public static function get_theme_data( $deprecated = array(), $options = array()
$theme_json_data = static::read_json_file( $theme_json_file );
$theme_json_data = static::translate( $theme_json_data, $wp_theme->get( 'TextDomain' ) );
} else {
$theme_json_data = array();
$theme_json_data = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA );
}

/**
Expand Down Expand Up @@ -310,6 +311,32 @@ public static function get_theme_data( $deprecated = array(), $options = array()
}
$theme_support_data['settings']['color']['defaultGradients'] = $default_gradients;

if ( ! isset( $theme_support_data['settings']['typography'] ) ) {
$theme_support_data['settings']['typography'] = array();
}
$default_font_sizes = false;
if ( current_theme_supports( 'default-font-sizes' ) ) {
$default_font_sizes = true;
}
if ( ! isset( $theme_support_data['settings']['typography']['fontSizes'] ) ) {
// If the theme does not have any font sizes, we still want to show the core one.
$default_font_sizes = true;
}
$theme_support_data['settings']['typography']['defaultFontSizes'] = $default_font_sizes;

if ( ! isset( $theme_support_data['settings']['spacing'] ) ) {
$theme_support_data['settings']['spacing'] = array();
}
$default_spacing_sizes = false;
if ( current_theme_supports( 'default-spacing-sizes' ) ) {
$default_spacing_sizes = true;
}
if ( ! isset( $theme_support_data['settings']['spacing']['spacingSizes'] ) ) {
// If the theme does not have any spacing sizes, we still want to show the core one.
$default_spacing_sizes = true;
}
$theme_support_data['settings']['spacing']['defaultSpacingSizes'] = $default_spacing_sizes;

if ( ! isset( $theme_support_data['settings']['shadow'] ) ) {
$theme_support_data['settings']['shadow'] = array();
}
Expand Down Expand Up @@ -359,7 +386,7 @@ public static function get_block_data() {
return static::$blocks;
}

$config = array( 'version' => 2 );
$config = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA );
foreach ( $blocks as $block_name => $block_type ) {
if ( isset( $block_type->supports['__experimentalStyle'] ) ) {
$config['styles']['blocks'][ $block_name ] = static::remove_json_comments( $block_type->supports['__experimentalStyle'] );
Expand Down Expand Up @@ -494,6 +521,7 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post
* Returns the user's origin config.
*
* @since 5.9.0
* @since 6.6.0 The 'isGlobalStylesUserThemeJSON' flag is left on the user data.
*
* @return WP_Theme_JSON Entity that holds styles for user data.
*/
Expand Down Expand Up @@ -531,14 +559,18 @@ public static function get_user_data() {
isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) &&
$decoded_data['isGlobalStylesUserThemeJSON']
) {
unset( $decoded_data['isGlobalStylesUserThemeJSON'] );
$config = $decoded_data;
}
}

/** This filter is documented in wp-includes/class-wp-theme-json-resolver.php */
$theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) );
static::$user = $theme_json->get_theme_json();
$theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) );
$config = $theme_json->get_data();

// Needs to be set for schema migrations of user data.
$config['isGlobalStylesUserThemeJSON'] = true;

static::$user = new WP_Theme_JSON( $config, 'custom' );

return static::$user;
}
Expand Down Expand Up @@ -586,7 +618,6 @@ public static function get_merged_data( $origin = 'custom' ) {
$result = new WP_Theme_JSON();
$result->merge( static::get_core_data() );
if ( 'default' === $origin ) {
$result->set_spacing_sizes();
return $result;
}

Expand All @@ -597,12 +628,10 @@ public static function get_merged_data( $origin = 'custom' ) {

$result->merge( static::get_theme_data() );
if ( 'theme' === $origin ) {
$result->set_spacing_sizes();
return $result;
}

$result->merge( static::get_user_data() );
$result->set_spacing_sizes();

return $result;
}
Expand Down
93 changes: 91 additions & 2 deletions wp-includes/class-wp-theme-json-schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class WP_Theme_JSON_Schema {
* Function that migrates a given theme.json structure to the last version.
*
* @since 5.9.0
* @since 6.6.0 Migrate up to v3.
*
* @param array $theme_json The structure to migrate.
*
Expand All @@ -47,8 +48,14 @@ public static function migrate( $theme_json ) {
);
}

if ( 1 === $theme_json['version'] ) {
$theme_json = self::migrate_v1_to_v2( $theme_json );
// Migrate each version in order starting with the current version.
switch ( $theme_json['version'] ) {
case 1:
$theme_json = self::migrate_v1_to_v2( $theme_json );
// no break
case 2:
$theme_json = self::migrate_v2_to_v3( $theme_json );
// no break
}

return $theme_json;
Expand Down Expand Up @@ -84,6 +91,88 @@ private static function migrate_v1_to_v2( $old ) {
return $new;
}

/**
* Migrates from v2 to v3.
*
* - Sets settings.typography.defaultFontSizes to false.
*
* @since 6.6.0
*
* @param array $old Data to migrate.
*
* @return array Data with defaultFontSizes set to false.
*/
private static function migrate_v2_to_v3( $old ) {
// Copy everything.
$new = $old;

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

/*
* Remaining changes do not need to be applied to the custom origin,
* as they should take on the value of the theme origin.
*/
if (
isset( $new['isGlobalStylesUserThemeJSON'] ) &&
true === $new['isGlobalStylesUserThemeJSON']
) {
return $new;
}

/*
* Even though defaultFontSizes and defaultSpacingSizes are new
* settings, we need to migrate them as they each control
* PRESETS_METADATA prevent_override values which were previously
* hardcoded to false. This only needs to happen when the theme provides
* fontSizes or spacingSizes as they could match the default ones and
* affect the generated CSS.
*/
if ( isset( $old['settings']['typography']['fontSizes'] ) ) {
if ( ! isset( $new['settings'] ) ) {
$new['settings'] = array();
}
if ( ! isset( $new['settings']['typography'] ) ) {
$new['settings']['typography'] = array();
}
$new['settings']['typography']['defaultFontSizes'] = false;
}

/*
* Similarly to defaultFontSizes, we need to migrate defaultSpacingSizes
* as it controls the PRESETS_METADATA prevent_override which was
* previously hardcoded to false. This only needs to happen when the
* theme provided spacing sizes via spacingSizes or spacingScale.
*/
if (
isset( $old['settings']['spacing']['spacingSizes'] ) ||
isset( $old['settings']['spacing']['spacingScale'] )
) {
if ( ! isset( $new['settings'] ) ) {
$new['settings'] = array();
}
if ( ! isset( $new['settings']['spacing'] ) ) {
$new['settings']['spacing'] = array();
}
$new['settings']['spacing']['defaultSpacingSizes'] = false;
}

/*
* In v3 spacingSizes is merged with the generated spacingScale sizes
* instead of completely replacing them. The v3 behavior is what was
* documented for the v2 schema, but the code never actually did work
* that way. Instead of surprising users with a behavior change two
* years after the fact at the same time as a v3 update is introduced,
* we'll continue using the "bugged" behavior for v2 themes. And treat
* the "bug fix" as a breaking change for v3.
*/
if ( isset( $old['settings']['spacing']['spacingSizes'] ) ) {
unset( $new['settings']['spacing']['spacingScale'] );
}

return $new;
}

/**
* Processes the settings subtree.
*
Expand Down
Loading

0 comments on commit 5b9f383

Please sign in to comment.