From bbb85de12dc9a04e9751f69fc784b476eecea5d2 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 14 Sep 2023 08:50:43 +0000 Subject: [PATCH] Themes: Inject `theme` attribute during serialization. Rather than using `_inject_theme_attribute_in_block_template_content` to inject the `theme` attribute into all Template Part blocks found in a given file-based Block Template, introduce a new function called `_inject_theme_attribute_in_template_part_block`, and use that as second argument to `serialize_blocks()` (introduced in [56557]) in order to inject said attribute during tree traversal for serialization. This allows for a more modular approach that will eventually be extended to implement automatic insertion of hooked blocks. Note that we're guarding `_build_block_template_result_from_file()` (i.e. the callsite of `_inject_theme_attribute_in_template_part_block` and previously of `_inject_theme_attribute_in_block_template_content`) against regressions through additional unit test coverage added in [56562]. Props @gziolo. Fixes #59338. See #59313. git-svn-id: https://develop.svn.wordpress.org/trunk@56578 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-template-utils.php | 24 +++++- ...te-part-with-existing-theme-attribute.html | 2 +- tests/phpunit/tests/block-template-utils.php | 80 ++++++++++++++++++- 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/block-template-utils.php b/src/wp-includes/block-template-utils.php index b8538ee3b4..460372b8cc 100644 --- a/src/wp-includes/block-template-utils.php +++ b/src/wp-includes/block-template-utils.php @@ -513,6 +513,26 @@ function _inject_theme_attribute_in_block_template_content( $template_content ) return $template_content; } +/** + * Injects the active theme's stylesheet as a `theme` attribute + * into a given template part block. + * + * @since 6.4.0 + * @access private + * + * @param array $block a parsed block. + * @return array Updated block. + */ +function _inject_theme_attribute_in_template_part_block( $block ) { + if ( + 'core/template-part' === $block['blockName'] && + ! isset( $block['attrs']['theme'] ) + ) { + $block['attrs']['theme'] = get_stylesheet(); + } + return $block; +} + /** * Parses a block template and removes the theme attribute from each template part. * @@ -565,7 +585,6 @@ function _build_block_template_result_from_file( $template_file, $template_type $template = new WP_Block_Template(); $template->id = $theme . '//' . $template_file['slug']; $template->theme = $theme; - $template->content = _inject_theme_attribute_in_block_template_content( $template_content ); $template->slug = $template_file['slug']; $template->source = 'theme'; $template->type = $template_type; @@ -589,6 +608,9 @@ function _build_block_template_result_from_file( $template_file, $template_type $template->area = $template_file['area']; } + $blocks = parse_blocks( $template_content ); + $template->content = serialize_blocks( $blocks, '_inject_theme_attribute_in_template_part_block' ); + return $template; } diff --git a/tests/phpunit/data/templates/template-with-template-part-with-existing-theme-attribute.html b/tests/phpunit/data/templates/template-with-template-part-with-existing-theme-attribute.html index d5f92e7d11..8e4678c8d0 100644 --- a/tests/phpunit/data/templates/template-with-template-part-with-existing-theme-attribute.html +++ b/tests/phpunit/data/templates/template-with-template-part-with-existing-theme-attribute.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/tests/phpunit/tests/block-template-utils.php b/tests/phpunit/tests/block-template-utils.php index 7c5e8dd595..efeae8a392 100644 --- a/tests/phpunit/tests/block-template-utils.php +++ b/tests/phpunit/tests/block-template-utils.php @@ -208,7 +208,7 @@ class Tests_Block_Template_Utils extends WP_UnitTestCase { ), 'a template with a template part block with an existing theme attribute' => array( 'filename' => 'template-with-template-part-with-existing-theme-attribute.html', - 'expected' => '', + 'expected' => '', ), 'a template with no template part block' => array( 'filename' => 'template.html', @@ -219,6 +219,84 @@ class Tests_Block_Template_Utils extends WP_UnitTestCase { ); } + /** + * @ticket 59338 + * + * @covers ::test_inject_theme_attribute_in_template_part_block + */ + public function test_inject_theme_attribute_in_template_part_block() { + $template_part_block_without_theme_attribute = array( + 'blockName' => 'core/template-part', + 'attrs' => array( + 'slug' => 'header', + 'align' => 'full', + 'tagName' => 'header', + 'className' => 'site-header', + ), + 'innerHTML' => '', + 'innerContent' => array(), + 'innerBlocks' => array(), + ); + + $actual = _inject_theme_attribute_in_template_part_block( $template_part_block_without_theme_attribute ); + $expected = array( + 'blockName' => 'core/template-part', + 'attrs' => array( + 'slug' => 'header', + 'align' => 'full', + 'tagName' => 'header', + 'className' => 'site-header', + 'theme' => get_stylesheet(), + ), + 'innerHTML' => '', + 'innerContent' => array(), + 'innerBlocks' => array(), + ); + $this->assertSame( + $expected, + $actual, + '`theme` attribute was not correctly injected in template part block.' + ); + + // Does not inject theme when there is an existing theme attribute. + $template_part_block_with_existing_theme_attribute = array( + 'blockName' => 'core/template-part', + 'attrs' => array( + 'slug' => 'header', + 'align' => 'full', + 'tagName' => 'header', + 'className' => 'site-header', + 'theme' => 'fake-theme', + ), + 'innerHTML' => '', + 'innerContent' => array(), + 'innerBlocks' => array(), + ); + + $actual = _inject_theme_attribute_in_template_part_block( $template_part_block_with_existing_theme_attribute ); + $this->assertSame( + $template_part_block_with_existing_theme_attribute, + $actual, + 'Existing `theme` attribute in template part block was not respected by attribute injection.' + ); + + // Does not inject theme when there is no template part. + $non_template_part_block = array( + 'blockName' => 'core/post-content', + 'attrs' => array(), + 'innerHTML' => '', + 'innerContent' => array(), + 'innerBlocks' => array(), + ); + + $actual = _inject_theme_attribute_in_template_part_block( $non_template_part_block ); + $this->assertSame( + $non_template_part_block, + $actual, + '`theme` attribute injection modified non-template-part block.' + ); + } + public function test_inject_theme_attribute_in_block_template_content() { $theme = get_stylesheet(); $content_without_theme_attribute = '';