Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/silver-cups-explode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wpengine/wp-graphql-content-blocks": minor
---

feat: add support for resolving Template Part blocks
32 changes: 31 additions & 1 deletion includes/Data/ContentBlocksResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private static function handle_do_block( array $block ): ?array {
$block['clientId'] = uniqid();

// @todo apply more hydrations.

$block = self::populate_template_part_inner_blocks( $block );
$block = self::populate_reusable_blocks( $block );

$block = self::populate_pattern_inner_blocks( $block );
Expand Down Expand Up @@ -183,6 +183,36 @@ private static function is_block_empty( array $block ): bool {
return empty( trim( $stripped ?? '' ) );
}

/**
* Populates the innerBlocks of a template part block with the blocks from the template part.
*
* @param array<string,mixed> $block The block to populate.
*
* @return array<string,mixed> The populated block.
*/
private static function populate_template_part_inner_blocks( array $block ): array {
// Bail if not WP 5.8 or later.
if ( ! function_exists( 'get_block_templates' ) ) {
return $block;
}

if ( 'core/template-part' !== $block['blockName'] || ! isset( $block['attrs']['slug'] ) ) {
return $block;
}

$matching_templates = get_block_templates( [ 'slug__in' => [ $block['attrs']['slug'] ] ], 'wp_template_part' );

$template_blocks = ! empty( $matching_templates[0]->content ) ? self::parse_blocks( $matching_templates[0]->content ) : null;

if ( empty( $template_blocks ) ) {
return $block;
}

$block['innerBlocks'] = $template_blocks;

return $block;
}

/**
* Populates reusable blocks with the blocks from the reusable ref ID.
*
Expand Down
54 changes: 54 additions & 0 deletions tests/unit/ContentBlocksResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,58 @@ public function test_resolve_content_blocks_resolves_pattern_inner_blocks() {
// Cleanup: Unregistering the pattern.
unregister_block_pattern( $pattern_name );
}

/**
* Tests that template part inner blocks are resolved correctly.
*/
public function test_resolve_content_blocks_resolves_template_part_inner_blocks() {
// Skip if template part functionality is not supported
if ( ! function_exists( 'get_block_templates' ) ) {
$this->markTestSkipped( 'Template part functionality not supported in this WordPress version.' );
}

// Mock the get_block_templates function to control the output.
$mock_template = (object) [
'content' => '<!-- wp:paragraph /--><!-- wp:heading /-->',
];

add_filter(
'get_block_templates',
function () use ( $mock_template ) {
return [ $mock_template ];
}
);

// Update post content to include template part block
$post_content = '
<!-- wp:template-part {"slug":"test-template-part"} /-->
';

wp_update_post(
[
'ID' => $this->post_id,
'post_content' => $post_content,
]
);

$post_model = new Post( get_post( $this->post_id ) );

// Resolve blocks as nested
$resolved_blocks = $this->instance->resolve_content_blocks( $post_model, [ 'flat' => false ] );

// Assertions
$this->assertCount( 1, $resolved_blocks, 'There should be only one top-level block (template-part).' );
$this->assertEquals( 'core/template-part', $resolved_blocks[0]['blockName'] );
$this->assertCount( 2, $resolved_blocks[0]['innerBlocks'], 'There should be two inner blocks in the template part.' );
$this->assertEquals( 'core/paragraph', $resolved_blocks[0]['innerBlocks'][0]['blockName'] );
$this->assertEquals( 'core/heading', $resolved_blocks[0]['innerBlocks'][1]['blockName'] );

// Resolve blocks as flat
$resolved_flat_blocks = $this->instance->resolve_content_blocks( $post_model, [ 'flat' => true ] );

$this->assertCount( 3, $resolved_flat_blocks, 'There should be three blocks when flattened.' );
$this->assertEquals( 'core/template-part', $resolved_flat_blocks[0]['blockName'] );
$this->assertEquals( 'core/paragraph', $resolved_flat_blocks[1]['blockName'] );
$this->assertEquals( 'core/heading', $resolved_flat_blocks[2]['blockName'] );
}
}
Loading