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: |
|
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.
Blocks with render callbacks that require the
WP_Blockinstance argument fortunately seem to be the exception rather than the rule. However, we should probably try to makeWP_Block_Type::render()work for them regardless.One way to do so would be to create a
WP_Blockinstance on the fly. This would however also require parsing the block$content. If done unconditionally -- i.e. even when aWP_Blockinstance 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_callbackexpects. Although that's also not exactly elegant...