diff --git a/lib/blocks.php b/lib/blocks.php index e28971bad032c2..efcc33bd7fbf4b 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -104,7 +104,7 @@ function gutenberg_render_block( $block ) { if ( $block_name ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_name ); if ( null !== $block_type && $block_type->is_dynamic() ) { - return $block_type->render( $attributes ); + return $block_type->render( $attributes, $raw_content ); } } @@ -146,6 +146,7 @@ function do_blocks( $content ) { $offset = $block_match[0][1]; $block_name = $block_match[1][0]; $is_self_closing = isset( $block_match[4] ); + $block_content = ''; // Reset attributes JSON to prevent scope bleed from last iteration. $block_attributes_json = null; @@ -177,9 +178,6 @@ function do_blocks( $content ) { } } - // Replace dynamic block with server-rendered output. - $rendered_content .= $block_type->render( $attributes ); - if ( ! $is_self_closing ) { $end_tag_pattern = '//'; if ( ! preg_match( $end_tag_pattern, $content, $block_match_end, PREG_OFFSET_CAPTURE ) ) { @@ -192,6 +190,13 @@ function do_blocks( $content ) { $end_tag = $block_match_end[0][0]; $end_offset = $block_match_end[0][1]; + $block_content = substr( $content, 0, $end_offset ); + } + + // Replace dynamic block with server-rendered output. + $rendered_content .= $block_type->render( $attributes, $block_content ); + + if ( ! $is_self_closing ) { $content = substr( $content, $end_offset + strlen( $end_tag ) ); } } diff --git a/lib/class-wp-block-type.php b/lib/class-wp-block-type.php index 39f08e54fddc28..22f68a2deeadd2 100644 --- a/lib/class-wp-block-type.php +++ b/lib/class-wp-block-type.php @@ -94,17 +94,18 @@ public function __construct( $block_type, $args = array() ) { * * @since 0.6.0 * - * @param array $attributes Optional. Block attributes. Default empty array. + * @param array $attributes Optional. Block attributes. Default empty array. + * @param string $content Optional. Block content. Default empty string. * @return string Rendered block type output. */ - public function render( $attributes = array() ) { + public function render( $attributes = array(), $content = '' ) { if ( ! $this->is_dynamic() ) { - return ''; + return $content; } $attributes = $this->prepare_attributes_for_render( $attributes ); - return (string) call_user_func( $this->render_callback, $attributes ); + return (string) call_user_func( $this->render_callback, $attributes, $content, $this ); } /** diff --git a/phpunit/class-block-type-test.php b/phpunit/class-block-type-test.php index 8a08cb112dcf28..62cc4b2d8356ec 100644 --- a/phpunit/class-block-type-test.php +++ b/phpunit/class-block-type-test.php @@ -36,13 +36,20 @@ function test_render() { $this->assertEquals( $attributes, json_decode( $output, true ) ); } - function test_render_for_static_block() { + function test_render_for_static_block_default() { $block_type = new WP_Block_Type( 'core/dummy', array() ); $output = $block_type->render(); $this->assertEquals( '', $output ); } + function test_render_for_static_block_with_content() { + $block_type = new WP_Block_Type( 'core/dummy', array() ); + $output = $block_type->render( array(), 'some dummy content' ); + + $this->assertEquals( 'some dummy content', $output ); + } + function test_is_dynamic_for_static_block() { $block_type = new WP_Block_Type( 'core/dummy', array() ); @@ -57,6 +64,15 @@ function test_is_dynamic_for_dynamic_block() { $this->assertTrue( $block_type->is_dynamic() ); } + function test_dynamic_block_with_content() { + $block_type = new WP_Block_Type( 'core/dummy', array( + 'render_callback' => array( $this, 'render_dummy_block_with_content' ), + ) ); + $output = json_decode( $block_type->render( array(), 'hello world' ), true ); + $this->assertEquals( 'hello world', $output['_content'] ); + $this->assertEquals( 'core/dummy', $output['_block_name'] ); + } + function test_prepare_attributes() { $attributes = array( 'correct' => 'include', @@ -99,8 +115,9 @@ function render_dummy_block( $attributes ) { return json_encode( $attributes ); } - function render_dummy_block_with_content( $attributes, $content ) { - $attributes['_content'] = $content; + function render_dummy_block_with_content( $attributes, $content, $instance ) { + $attributes['_content'] = $content; + $attributes['_block_name'] = $instance->name; return json_encode( $attributes ); } diff --git a/phpunit/class-dynamic-blocks-render-test.php b/phpunit/class-dynamic-blocks-render-test.php index a642184fc99a5b..559d91e14793a4 100644 --- a/phpunit/class-dynamic-blocks-render-test.php +++ b/phpunit/class-dynamic-blocks-render-test.php @@ -24,9 +24,9 @@ class Dynamic_Blocks_Render_Test extends WP_UnitTestCase { * * @return string Block output. */ - function render_dummy_block( $attributes ) { + function render_dummy_block( $attributes, $content = '' ) { $this->dummy_block_instance_number += 1; - return $this->dummy_block_instance_number . ':' . $attributes['value']; + return $this->dummy_block_instance_number . ':' . $attributes['value'] . ':' . $content; } /** @@ -51,7 +51,7 @@ function tearDown() { } /** - * Test dynamic blocks that lack content, including void blocks. + * Test dynamic blocks, including void blocks. * * @covers ::do_blocks */ @@ -68,21 +68,22 @@ function test_dynamic_block_rendering() { $post_content = 'before' . '' . - '' . + 'hello world' . 'between' . '' . '' . 'after'; $updated_post_content = do_blocks( $post_content ); - $this->assertEquals( $updated_post_content, + $this->assertEquals( 'before' . - '1:b1' . - '2:b1' . + '1:b1:' . + '2:b1:hello world' . 'between' . - '3:b2' . - '4:b2' . - 'after' + '3:b2:' . + '4:b2:' . + 'after', + $updated_post_content ); }