Skip to content

Commit c46e021

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

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
// Prepare innerBlocks.
@@ -181,6 +181,36 @@ private static function is_block_empty( array $block ): bool {
181181
return empty( trim( $stripped ?? '' ) );
182182
}
183183

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

tests/unit/ContentBlocksResolverTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,4 +349,58 @@ protected function assertEqualBlocks( $expected, $actual, $message = '' ) {
349349
$this->assertEqualBlocks( $expected_inner_block, $actual_inner_blocks[ $index ], $message );
350350
}
351351
}
352+
353+
/**
354+
* Tests that template part inner blocks are resolved correctly.
355+
*/
356+
public function test_resolve_content_blocks_resolves_template_part_inner_blocks() {
357+
// Skip if template part functionality is not supported
358+
if ( ! function_exists( 'get_block_templates' ) ) {
359+
$this->markTestSkipped( 'Template part functionality not supported in this WordPress version.' );
360+
}
361+
362+
// Mock the get_block_templates function to control the output.
363+
$mock_template = (object) [
364+
'content' => '<!-- wp:paragraph /--><!-- wp:heading /-->',
365+
];
366+
367+
add_filter(
368+
'get_block_templates',
369+
function () use ( $mock_template ) {
370+
return [ $mock_template ];
371+
}
372+
);
373+
374+
// Update post content to include template part block
375+
$post_content = '
376+
<!-- wp:template-part {"slug":"test-template-part"} /-->
377+
';
378+
379+
wp_update_post(
380+
[
381+
'ID' => $this->post_id,
382+
'post_content' => $post_content,
383+
]
384+
);
385+
386+
$post_model = new Post( get_post( $this->post_id ) );
387+
388+
// Resolve blocks as nested
389+
$resolved_blocks = $this->instance->resolve_content_blocks( $post_model, [ 'flat' => false ] );
390+
391+
// Assertions
392+
$this->assertCount( 1, $resolved_blocks, 'There should be only one top-level block (template-part).' );
393+
$this->assertEquals( 'core/template-part', $resolved_blocks[0]['blockName'] );
394+
$this->assertCount( 2, $resolved_blocks[0]['innerBlocks'], 'There should be two inner blocks in the template part.' );
395+
$this->assertEquals( 'core/paragraph', $resolved_blocks[0]['innerBlocks'][0]['blockName'] );
396+
$this->assertEquals( 'core/heading', $resolved_blocks[0]['innerBlocks'][1]['blockName'] );
397+
398+
// Resolve blocks as flat
399+
$resolved_flat_blocks = $this->instance->resolve_content_blocks( $post_model, [ 'flat' => true ] );
400+
401+
$this->assertCount( 3, $resolved_flat_blocks, 'There should be three blocks when flattened.' );
402+
$this->assertEquals( 'core/template-part', $resolved_flat_blocks[0]['blockName'] );
403+
$this->assertEquals( 'core/paragraph', $resolved_flat_blocks[1]['blockName'] );
404+
$this->assertEquals( 'core/heading', $resolved_flat_blocks[2]['blockName'] );
405+
}
352406
}

0 commit comments

Comments
 (0)