Make WordPress Core

Opened 7 weeks ago

Last modified 7 weeks ago

#64118 new defect (bug)

`WP_Block_Type::render` doesn’t pass block instance argument to render_callback

Reported by: bernhard-reiter's profile Bernhard Reiter Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: General Keywords:
Focuses: Cc:

Description

The WP_Block_Type class has a render method that allows rendering an instance of a dynamic block, without actually creating a WP_Block instance. This can be used e.g. in combination with WP_Block_Registry to render an instance of a block whose name and attributes are known:

$block_type = WP_Block_Type_Registry::get_instance()->get_registered( 'core/some-block' );
$output     = $block_type->render( array( 'someAttribute' => $attribute_value ) );

Internally, WP_Block_Type::render calls the block type's `render_callback`:

return (string) call_user_func( $this->render_callback, $attributes, $content );

However, a block's render_callback can include a third argument: a WP_Block instance. The latter is passed to the callback when invoked from WP_Block::render:

$block_content = (string) call_user_func( $this->block_type->render_callback, $this->attributes, $block_content, $this );

This means that for a dynamic block whose render callback expects three arguments (including the WP_Block instance), calling WP_Block_Type::render will fail, since it does not pass the latter.

---

An instance of this problem was observed and reported by @ellatrix while preparing the package sync PR for WordPress 6.9. It was caused by unit tests that created block markup for the synced pattern block (core/block). She fixed it by changing the tests to create an actual WP_Block instance.

Change History (3)

This ticket was mentioned in Slack in #core-editor by bernhardreiter. View the logs.


7 weeks ago

#2 @Bernhard Reiter
7 weeks ago

Blocks with render callbacks that require the WP_Block instance argument fortunately seem to be the exception rather than the rule. However, we should probably try to make WP_Block_Type::render() work for them regardless.

One way to do so would be to create a WP_Block instance on the fly. This would however also require parsing the block $content. If done unconditionally -- i.e. even when a WP_Block instance isn't needed -- this could impact performance rather negatively.

To remediate that, we could probably use PHP's introspection features to check how many arguments the render_callback expects. Although that's also not exactly elegant...

This ticket was mentioned in Slack in #core by amykamala. View the logs.


7 weeks ago

Note: See TracTickets for help on using tickets.