Skip to content

Commit ffb6c83

Browse files
justlevineTa5r
andcommitted
feat: add support for resolving Template Part blocks
Co-authored-by: Ta5r <[email protected]>
1 parent 4c548c3 commit ffb6c83

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

.changeset/silver-cups-explode.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wpengine/wp-graphql-content-blocks": minor
3+
---
4+
5+
feat: add support for resolving Template Part blocks

includes/Data/ContentBlocksResolver.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ private static function handle_do_block( array $block ): ?array {
148148
$block['clientId'] = uniqid();
149149

150150
// @todo apply more hydrations.
151-
151+
$block = self::populate_template_part_inner_blocks( $block );
152152
$block = self::populate_reusable_blocks( $block );
153153

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

186+
/**
187+
* Populates the innerBlocks of a template part block with the blocks from the template part.
188+
*
189+
* @param array<string,mixed> $block The block to populate.
190+
*
191+
* @return array<string,mixed> The populated block.
192+
*/
193+
private static function populate_template_part_inner_blocks( array $block ): array {
194+
// Bail if not WP 5.8 or later.
195+
if ( ! function_exists( 'get_block_templates' ) ) {
196+
return $block;
197+
}
198+
199+
if ( 'core/template-part' !== $block['blockName'] || ! isset( $block['attrs']['slug'] ) ) {
200+
return $block;
201+
}
202+
203+
$matching_templates = get_block_templates( [ 'slug__in' => [ $block['attrs']['slug'] ] ], 'wp_template_part' );
204+
205+
$template_blocks = ! empty( $matching_templates[0]->content ) ? self::parse_blocks( $matching_templates[0]->content ) : null;
206+
207+
if ( empty( $template_blocks ) ) {
208+
return $block;
209+
}
210+
211+
$block['innerBlocks'] = $template_blocks;
212+
213+
return $block;
214+
}
215+
186216
/**
187217
* Populates reusable blocks with the blocks from the reusable ref ID.
188218
*

tests/unit/ContentBlocksResolverTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,4 +413,58 @@ public function test_resolve_content_blocks_resolves_pattern_inner_blocks() {
413413
// Cleanup: Unregistering the pattern.
414414
unregister_block_pattern( $pattern_name );
415415
}
416+
417+
/**
418+
* Tests that template part inner blocks are resolved correctly.
419+
*/
420+
public function test_resolve_content_blocks_resolves_template_part_inner_blocks() {
421+
// Skip if template part functionality is not supported
422+
if ( ! function_exists( 'get_block_templates' ) ) {
423+
$this->markTestSkipped( 'Template part functionality not supported in this WordPress version.' );
424+
}
425+
426+
// Mock the get_block_templates function to control the output.
427+
$mock_template = (object) [
428+
'content' => '<!-- wp:paragraph /--><!-- wp:heading /-->',
429+
];
430+
431+
add_filter(
432+
'get_block_templates',
433+
function () use ( $mock_template ) {
434+
return [ $mock_template ];
435+
}
436+
);
437+
438+
// Update post content to include template part block
439+
$post_content = '
440+
<!-- wp:template-part {"slug":"test-template-part"} /-->
441+
';
442+
443+
wp_update_post(
444+
[
445+
'ID' => $this->post_id,
446+
'post_content' => $post_content,
447+
]
448+
);
449+
450+
$post_model = new Post( get_post( $this->post_id ) );
451+
452+
// Resolve blocks as nested
453+
$resolved_blocks = $this->instance->resolve_content_blocks( $post_model, [ 'flat' => false ] );
454+
455+
// Assertions
456+
$this->assertCount( 1, $resolved_blocks, 'There should be only one top-level block (template-part).' );
457+
$this->assertEquals( 'core/template-part', $resolved_blocks[0]['blockName'] );
458+
$this->assertCount( 2, $resolved_blocks[0]['innerBlocks'], 'There should be two inner blocks in the template part.' );
459+
$this->assertEquals( 'core/paragraph', $resolved_blocks[0]['innerBlocks'][0]['blockName'] );
460+
$this->assertEquals( 'core/heading', $resolved_blocks[0]['innerBlocks'][1]['blockName'] );
461+
462+
// Resolve blocks as flat
463+
$resolved_flat_blocks = $this->instance->resolve_content_blocks( $post_model, [ 'flat' => true ] );
464+
465+
$this->assertCount( 3, $resolved_flat_blocks, 'There should be three blocks when flattened.' );
466+
$this->assertEquals( 'core/template-part', $resolved_flat_blocks[0]['blockName'] );
467+
$this->assertEquals( 'core/paragraph', $resolved_flat_blocks[1]['blockName'] );
468+
$this->assertEquals( 'core/heading', $resolved_flat_blocks[2]['blockName'] );
469+
}
416470
}

0 commit comments

Comments
 (0)