Skip to content

Commit

Permalink
Section Styles: Register block style variations on init (#62461)
Browse files Browse the repository at this point in the history
Co-authored-by: aaronrobertshaw <[email protected]>
Co-authored-by: oandregal <[email protected]>
Co-authored-by: annezazu <[email protected]>
  • Loading branch information
4 people authored and ellatrix committed Jun 18, 2024
1 parent 2b5ac52 commit 2683156
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 23 deletions.
3 changes: 3 additions & 0 deletions backport-changelog/6.6/6756.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
https://github.com/WordPress/wordpress-develop/pull/6756

* https://github.com/WordPress/gutenberg/pull/62461
126 changes: 103 additions & 23 deletions lib/block-supports/block-style-variations.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,24 +209,20 @@ function gutenberg_render_block_style_variation_class_name( $block_content, $blo

/**
* Collects block style variation data for merging with theme.json data.
* As each block style variation is processed it is registered if it hasn't
* been already. This registration is required for later sanitization of
* theme.json data.
*
* @since 6.6.0
*
* @param array $variations Shared block style variations.
*
* @return array Block variations data to be merged under `styles.blocks`.
*/
function gutenberg_resolve_and_register_block_style_variations( $variations ) {
function gutenberg_resolve_block_style_variations( $variations ) {
$variations_data = array();

if ( empty( $variations ) ) {
return $variations_data;
}

$registry = WP_Block_Styles_Registry::get_instance();
$have_named_variations = ! wp_is_numeric_array( $variations );

foreach ( $variations as $key => $variation ) {
Expand All @@ -248,23 +244,9 @@ function gutenberg_resolve_and_register_block_style_variations( $variations ) {
* Block style variations read in via standalone theme.json partials
* need to have their name set to the kebab case version of their title.
*/
$variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] );
$variation_label = $variation['title'] ?? $variation_name;
$variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] );

foreach ( $supported_blocks as $block_type ) {
$registered_styles = $registry->get_registered_styles_for_block( $block_type );

// Register block style variation if it hasn't already been registered.
if ( ! array_key_exists( $variation_name, $registered_styles ) ) {
gutenberg_register_block_style(
$block_type,
array(
'name' => $variation_name,
'label' => $variation_label,
)
);
}

// Add block style variation data under current block type.
$path = array( $block_type, 'variations', $variation_name );
_wp_array_set( $variations_data, $path, $variation_data );
Expand Down Expand Up @@ -320,7 +302,7 @@ function gutenberg_merge_block_style_variations_data( $variations_data, $theme_j
function gutenberg_resolve_block_style_variations_from_theme_style_variation( $theme_json ) {
$theme_json_data = $theme_json->get_data();
$shared_variations = $theme_json_data['styles']['blocks']['variations'] ?? array();
$variations_data = gutenberg_resolve_and_register_block_style_variations( $shared_variations );
$variations_data = gutenberg_resolve_block_style_variations( $shared_variations );

return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json, 'user' );
}
Expand All @@ -337,7 +319,7 @@ function gutenberg_resolve_block_style_variations_from_theme_style_variation( $t
*/
function gutenberg_resolve_block_style_variations_from_theme_json_partials( $theme_json ) {
$block_style_variations = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations( 'block' );
$variations_data = gutenberg_resolve_and_register_block_style_variations( $block_style_variations );
$variations_data = gutenberg_resolve_block_style_variations( $block_style_variations );

return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json );
}
Expand All @@ -355,7 +337,7 @@ function gutenberg_resolve_block_style_variations_from_theme_json_partials( $the
function gutenberg_resolve_block_style_variations_from_primary_theme_json( $theme_json ) {
$theme_json_data = $theme_json->get_data();
$block_style_variations = $theme_json_data['styles']['blocks']['variations'] ?? array();
$variations_data = gutenberg_resolve_and_register_block_style_variations( $block_style_variations );
$variations_data = gutenberg_resolve_block_style_variations( $block_style_variations );

return gutenberg_merge_block_style_variations_data( $variations_data, $theme_json );
}
Expand Down Expand Up @@ -411,3 +393,101 @@ function gutenberg_enqueue_block_style_variation_styles() {
add_filter( 'wp_theme_json_data_theme', 'gutenberg_resolve_block_style_variations_from_styles_registry', 10, 1 );

add_filter( 'wp_theme_json_data_user', 'gutenberg_resolve_block_style_variations_from_theme_style_variation', 10, 1 );


/**
* Registers any block style variations contained within the provided
* theme.json data.
*
* @access private
*
* @param array $variations Shared block style variations.
*/
function gutenberg_register_block_style_variations_from_theme_json_data( $variations ) {
if ( empty( $variations ) ) {
return;
}

$registry = WP_Block_Styles_Registry::get_instance();
$have_named_variations = ! wp_is_numeric_array( $variations );

foreach ( $variations as $key => $variation ) {
$supported_blocks = $variation['blockTypes'] ?? array();

/*
* Standalone theme.json partial files for block style variations
* will have their styles under a top-level property by the same name.
* Variations defined within an existing theme.json or theme style
* variation will themselves already be the required styles data.
*/
$variation_data = $variation['styles'] ?? $variation;

if ( empty( $variation_data ) ) {
continue;
}

/*
* Block style variations read in via standalone theme.json partials
* need to have their name set to the kebab case version of their title.
*/
$variation_name = $have_named_variations ? $key : _wp_to_kebab_case( $variation['title'] );
$variation_label = $variation['title'] ?? $variation_name;

foreach ( $supported_blocks as $block_type ) {
$registered_styles = $registry->get_registered_styles_for_block( $block_type );

// Register block style variation if it hasn't already been registered.
if ( ! array_key_exists( $variation_name, $registered_styles ) ) {
register_block_style(
$block_type,
array(
'name' => $variation_name,
'label' => $variation_label,
)
);
}
}
}
}

/**
* Register shared block style variations defined by the theme.
*
* These can come in three forms:
* - the theme's theme.json
* - the theme's partials (standalone files in `/styles` that only define block style variations)
* - the user's theme.json (for example, theme style variations the user selected)
*
* @access private
*/
function gutenberg_register_block_style_variations_from_theme() {
// Partials from `/styles`.
$variations_partials = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations( 'block' );
gutenberg_register_block_style_variations_from_theme_json_data( $variations_partials );

/*
* Pull the data from the specific origin instead of the merged data.
* This is because, for 6.6, we only support registering block style variations
* for the 'theme' and 'custom' origins but not for 'default' (core theme.json)
* or 'custom' (theme.json in a block).
*
* When/If we add support for every origin, we should switch to using the public API
* instead, e.g.: wp_get_global_styles( array( 'blocks', 'variations' ) ).
*/

// theme.json of the theme.
$theme_json_theme = WP_Theme_JSON_Resolver_Gutenberg::get_theme_data();
$variations_theme = $theme_json_theme->get_data()['styles']['blocks']['variations'] ?? array();
gutenberg_register_block_style_variations_from_theme_json_data( $variations_theme );

// User data linked for this theme.
$theme_json_user = WP_Theme_JSON_Resolver_Gutenberg::get_user_data();
$variations_user = $theme_json_user->get_data()['styles']['blocks']['variations'] ?? array();
gutenberg_register_block_style_variations_from_theme_json_data( $variations_user );
}

// Remove core init action registering variations.
if ( function_exists( 'wp_register_block_style_variations_from_theme' ) ) {
remove_action( 'init', 'wp_register_block_style_variations_from_theme' );
}
add_action( 'init', 'gutenberg_register_block_style_variations_from_theme' );
5 changes: 5 additions & 0 deletions phpunit/block-supports/block-style-variations-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public function filter_set_theme_root() {
public function test_add_registered_block_styles_to_theme_data() {
switch_theme( 'block-theme' );

// Trigger block style registration that occurs on `init` action.
// do_action( 'init' ) could be used here however this direct call
// means only the updates being tested are performed.
gutenberg_register_block_style_variations_from_theme();

$variation_styles_data = array(
'color' => array(
'background' => 'darkslateblue',
Expand Down

0 comments on commit 2683156

Please sign in to comment.