Skip to content

Commit

Permalink
Editor: Fix bug where it was not possible to style custom block eleme…
Browse files Browse the repository at this point in the history
…nts in `theme.json`.

This changeset resolves a bug where WordPress would only allow HTML elements within core's own blocks to be styled in `theme.json`. Prior to this change, any `theme.json` rules applying to elements in custom blocks were ignored. With this fix it is now possible to style third-party block elements in `theme.json`.

Props flixos90, azaozz, costdev, glendaviesnz, spacedmonkey, oandregal.
Fixes #57868.


git-svn-id: https://develop.svn.wordpress.org/trunk@56254 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
felixarntz committed Jul 18, 2023
1 parent 2e64ff8 commit 2b931da
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 14 deletions.
59 changes: 45 additions & 14 deletions src/wp-includes/global-styles-and-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,20 +320,10 @@ function wp_add_global_styles_for_blocks() {

// The likes of block element styles from theme.json do not have $metadata['name'] set.
if ( ! isset( $metadata['name'] ) && ! empty( $metadata['path'] ) ) {
$result = array_values(
array_filter(
$metadata['path'],
static function ( $item ) {
if ( str_contains( $item, 'core/' ) ) {
return true;
}
return false;
}
)
);
if ( isset( $result[0] ) ) {
if ( str_starts_with( $result[0], 'core/' ) ) {
$block_name = str_replace( 'core/', '', $result[0] );
$block_name = wp_get_block_name_from_theme_json_path( $metadata['path'] );
if ( $block_name ) {
if ( str_starts_with( $block_name, 'core/' ) ) {
$block_name = str_replace( 'core/', '', $block_name );
$stylesheet_handle = 'wp-block-' . $block_name;
}
wp_add_inline_style( $stylesheet_handle, $block_css );
Expand All @@ -342,6 +332,47 @@ static function ( $item ) {
}
}

/**
* Gets the block name from a given theme.json path.
*
* @since 6.3.0
* @access private
*
* @param array $path An array of keys describing the path to a property in theme.json.
* @return string Identified block name, or empty string if none found.
*/
function wp_get_block_name_from_theme_json_path( $path ) {
// Block name is expected to be the third item after 'styles' and 'blocks'.
if (
count( $path ) >= 3
&& 'styles' === $path[0]
&& 'blocks' === $path[1]
&& str_contains( $path[2], '/' )
) {
return $path[2];
}

/*
* As fallback and for backward compatibility, allow any core block to be
* at any position.
*/
$result = array_values(
array_filter(
$path,
static function ( $item ) {
if ( str_contains( $item, 'core/' ) ) {
return true;
}
return false;
}
)
);
if ( isset( $result[0] ) ) {
return $result[0];
}
return '';
}

/**
* Checks whether a theme or its parent has a theme.json file.
*
Expand Down
7 changes: 7 additions & 0 deletions tests/phpunit/data/themedir1/block-theme/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@
"my/third-party-block": {
"color": {
"background": "hotpink"
},
"elements": {
"cite": {
"color": {
"text": "white"
}
}
}
}
},
Expand Down
82 changes: 82 additions & 0 deletions tests/phpunit/tests/theme/wpAddGlobalStylesForBlocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,88 @@ public function test_blocks_inline_styles_get_rendered() {
);
}

/**
* @ticket 57868
*/
public function test_third_party_blocks_inline_styles_for_elements_get_rendered_when_per_block() {
$this->set_up_third_party_block();
add_filter( 'should_load_separate_core_block_assets', '__return_true' );

wp_register_style( 'global-styles', false, array(), true, true );
wp_enqueue_style( 'global-styles' );
wp_add_global_styles_for_blocks();

$actual = get_echo( 'wp_print_styles' );

$this->assertStringContainsString(
'.wp-block-my-third-party-block cite{color: white;}',
$actual
);
}

/**
* @ticket 57868
*/
public function test_third_party_blocks_inline_styles_for_elements_get_rendered() {
wp_register_style( 'global-styles', false, array(), true, true );
wp_enqueue_style( 'global-styles' );
wp_add_global_styles_for_blocks();

$actual = get_echo( 'wp_print_styles' );

$this->assertStringContainsString(
'.wp-block-my-third-party-block cite{color: white;}',
$actual
);
}

/**
* @ticket 57868
*
* @dataProvider data_wp_get_block_name_from_theme_json_path
*
* @param array $path An array of keys describing the path to a property in theme.json.
* @param string $expected The expected block name.
*/
public function test_wp_get_block_name_from_theme_json_path( $path, $expected ) {
$block_name = wp_get_block_name_from_theme_json_path( $path );
$this->assertSame( $expected, $block_name );
}

/**
* Data provider.
*
* @return array[]
*/
public function data_wp_get_block_name_from_theme_json_path() {
return array(
'core block styles' => array(
array( 'styles', 'blocks', 'core/navigation' ),
'core/navigation',
),
'core block element styles' => array(
array( 'styles', 'blocks', 'core/navigation', 'elements', 'link' ),
'core/navigation',
),
'custom block styles' => array(
array( 'styles', 'blocks', 'my/third-party-block' ),
'my/third-party-block',
),
'custom block element styles' => array(
array( 'styles', 'blocks', 'my/third-party-block', 'elements', 'cite' ),
'my/third-party-block',
),
'custom block wrong format' => array(
array( 'styles', 'my/third-party-block' ),
'',
),
'invalid path but works for BC' => array(
array( 'something', 'core/image' ),
'core/image',
),
);
}

private function set_up_third_party_block() {
switch_theme( 'block-theme' );

Expand Down

0 comments on commit 2b931da

Please sign in to comment.