Skip to content

Commit

Permalink
Update shape of theme.json and introduce the concept of elements (#30541
Browse files Browse the repository at this point in the history
)
  • Loading branch information
nosolosw authored May 5, 2021
1 parent b519a76 commit 0d93c15
Show file tree
Hide file tree
Showing 24 changed files with 2,397 additions and 1,242 deletions.
22 changes: 5 additions & 17 deletions docs/how-to-guides/themes/theme-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,30 +393,18 @@ add_theme_support('custom-spacing');

## Experimental — Link color control

Using the Gutenberg plugin (version 8.3 or later), link color control is available to the Paragraph, Heading, Group, Columns, and Media & Text blocks. This is off by default, and requires the theme to opt in by declaring support:
Using the Gutenberg plugin (version 8.3 or later), link color control is available to a number of blocks including Paragraph, Heading, Group, Columns, and Media & Text blocks. This is off by default, and requires the theme to opt in by declaring support:

```php
add_theme_support('experimental-link-color');
```

If a theme opts in, it should [define default link colors](/docs/how-to-guides/themes/theme-json.md#color-properties) in `experimental-theme.json` (or in its theme styles if no `experimental-theme.json` is present). For example:
If a theme opts in, it can [define link colors](/docs/how-to-guides/themes/theme-json.md#color-properties) by using the `experimental-theme.json`. If the theme doesn't use the `experimental-theme.json` it can configure the color of links by settings the value of the `--wp--style--color--link` CSS Custom Property such as:

```css
{
"global": {
"styles": {
"color": {
"link": "hotpink"
}
}
}
:root {
--wp--style--color--link: <value>;
}
```

If the theme styles the link color in its stylesheets (editor and front-end), it should ensure it maps to the `--wp--style--color--link` CSS variable:

```css
a {
color: var( --wp--style--color--link );
}
```
The framework will take care of enqueing the necessary rules for this to work. Whether or not the theme supports `experimental-theme.json` the presets will also be enqueued as CSS Custom Properties, so themes can also use `--wp--style--color-link: var(--wp--preset--color--<color-slug>)`. See [the docs](/docs/how-to-guides/themes/theme-json.md#color-properties) for details.
2 changes: 1 addition & 1 deletion lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$used_layout = $block['attrs']['layout'];
if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) {
$tree = WP_Theme_JSON_Resolver::get_merged_data( array(), 'theme' );
$default_layout = _wp_array_get( $tree->get_settings(), array( 'defaults', 'layout' ) );
$default_layout = _wp_array_get( $tree->get_settings(), array( 'layout' ) );
if ( ! $default_layout ) {
return $block_content;
}
Expand Down
8 changes: 4 additions & 4 deletions lib/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,13 @@ private static function translate( $theme_json, $domain = 'default' ) {
/*
* We need to process the paths that include '*' separately.
* One example of such a path would be:
* [ 'settings', '*', 'color', 'palette' ]
* [ 'settings', 'blocks', '*', 'color', 'palette' ]
*/
$nodes_to_iterate = array_keys( $path, '*', true );
if ( ! empty( $nodes_to_iterate ) ) {
/*
* At the moment, we only need to support one '*' in the path, so take it directly.
* - base will be [ 'settings' ]
* - base will be [ 'settings', 'blocks' ]
* - data will be [ 'color', 'palette' ]
*/
$base_path = array_slice( $path, 0, $nodes_to_iterate[0] );
Expand All @@ -219,7 +219,7 @@ private static function translate( $theme_json, $domain = 'default' ) {
continue;
}

// Whole path will be [ 'settings', 'core/paragraph', 'color', 'palette' ].
// Whole path will be [ 'settings', 'blocks', 'core/paragraph', 'color', 'palette' ].
$whole_path = array_merge( $base_path, array( $node_name ), $data_path );
$translated_array = self::translate_theme_json_chunk( $array_to_translate, $key, $context, $domain );
gutenberg_experimental_set( $theme_json, $whole_path, $translated_array );
Expand Down Expand Up @@ -324,7 +324,7 @@ private static function get_user_data_from_custom_post_type( $should_create_cpt
} elseif ( $should_create_cpt ) {
$cpt_post_id = wp_insert_post(
array(
'post_content' => '{}',
'post_content' => '{"version": ' . WP_Theme_JSON::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }',
'post_status' => 'publish',
'post_title' => __( 'Custom Styles', 'default' ),
'post_type' => $post_type_filter,
Expand Down
125 changes: 73 additions & 52 deletions lib/class-wp-theme-json-schema-v0.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,28 @@ public static function parse( $old ) {
// Copy everything.
$new = $old;

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

$new['version'] = WP_Theme_JSON::LATEST_SCHEMA;

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 = array();
$blocks_to_consolidate = array(
'core/heading/h1' => 'core/heading',
'core/heading/h2' => 'core/heading',
Expand All @@ -153,30 +175,6 @@ public static function parse( $old ) {
'core/query-title/h6' => 'core/query-title',
);

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

$new['version'] = 1;

return $new;
}

/**
* Processes the settings subtree.
*
* @param array $settings Array to process.
* @param array $blocks_to_consolidate A list of blocks that are transformed.
*
* @return array The settings in the new format.
*/
private static function process_settings( $settings, $blocks_to_consolidate ) {
$new = array();

$paths_to_override = array(
array( 'color', 'palette' ),
array( 'color', 'gradients' ),
Expand Down Expand Up @@ -260,12 +258,33 @@ private static function process_settings( $settings, $blocks_to_consolidate ) {
* Processes the styles subtree.
*
* @param array $styles Array to process.
* @param array $blocks_to_consolidate A list of blocks that are transformed.
*
* @return array The styles in the new format.
*/
private static function process_styles( $styles, $blocks_to_consolidate ) {
$new = array();
private static function process_styles( $styles ) {
$new = array();
$block_heading = array(
'core/heading/h1' => 'h1',
'core/heading/h2' => 'h2',
'core/heading/h3' => 'h3',
'core/heading/h4' => 'h4',
'core/heading/h5' => 'h5',
'core/heading/h6' => 'h6',
);
$blocks_to_consolidate = array(
'core/post-title/h1' => 'core/post-title',
'core/post-title/h2' => 'core/post-title',
'core/post-title/h3' => 'core/post-title',
'core/post-title/h4' => 'core/post-title',
'core/post-title/h5' => 'core/post-title',
'core/post-title/h6' => 'core/post-title',
'core/query-title/h1' => 'core/query-title',
'core/query-title/h2' => 'core/query-title',
'core/query-title/h3' => 'core/query-title',
'core/query-title/h4' => 'core/query-title',
'core/query-title/h5' => 'core/query-title',
'core/query-title/h6' => 'core/query-title',
);

// Styles within root become top-level.
if ( isset( $styles[ self::ROOT_BLOCK_NAME ] ) ) {
Expand All @@ -287,9 +306,9 @@ private static function process_styles( $styles, $blocks_to_consolidate ) {
* At this point, it only contains block's data.
* However, we still need to consolidate a few things:
*
* - link element => tranform from link color property
* - link element => transform from link color property
* - heading elements => consolidate multiple blocks (core/heading/h1, core/heading/h2)
* into a single one with elements (core/heading with elements h1, h2, etc).
* into a single one (core/heading).
*/
$new['blocks'] = $styles;

Expand All @@ -301,38 +320,40 @@ private static function process_styles( $styles, $blocks_to_consolidate ) {
}
}

// heading elements.
foreach ( $blocks_to_consolidate as $old_name => $new_name ) {
/*
* The heading block needs a special treatment:
*
* - if it has a link color => it needs to be moved to the blocks.core/heading
* - the rest is consolidated into the corresponding element
*
*/
foreach ( $block_heading as $old_name => $new_name ) {
if ( ! isset( $new['blocks'][ $old_name ] ) ) {
continue;
}

if ( ! isset( $new['blocks'][ $new_name ] ) ) {
$new['blocks'][ $new_name ] = array();
}
gutenberg_experimental_set( $new, array( 'elements', $new_name ), $new['blocks'][ $old_name ] );

/*
* First, port the existing link color element to the block,
* overriding the previous value.
*/
if ( isset( $new['blocks'][ $old_name ]['elements'] ) ) {
$new['blocks'][ $new_name ]['elements']['link'] = $new['blocks'][ $old_name ]['elements']['link'];
unset( $new['blocks'][ $old_name ]['elements'] );
gutenberg_experimental_set( $new, array( 'blocks', 'core/heading', 'elements' ), $new['blocks'][ $old_name ]['elements'] );
}

/*
* Then, port any style categories left to the element
* resulting of exploding the previous block selector:
*
* - core/heading/h1 => h1 element
* - core/heading/h2 => h2 element
* - and so on
*/
if ( isset( $new['blocks'][ $old_name ] ) ) {
$element_name = explode( '/', $old_name )[2];
$new['blocks'][ $new_name ]['elements'][ $element_name ] = $new['blocks'][ $old_name ];
unset( $new['blocks'][ $old_name ] );
unset( $new['blocks'][ $old_name ] );

}

/*
* Port the styles from the old blocks to the new,
* overriding the previous values.
*/
foreach ( $blocks_to_consolidate as $old_name => $new_name ) {
if ( ! isset( $new['blocks'][ $old_name ] ) ) {
continue;
}

gutenberg_experimental_set( $new, array( 'blocks', $new_name ), $new['blocks'][ $old_name ] );
unset( $new['blocks'][ $old_name ] );

}

return $new;
Expand Down
Loading

0 comments on commit 0d93c15

Please sign in to comment.