Editor: Move pre_render_block, render_block_data, render_block_context (Attempt #2)#765
Editor: Move pre_render_block, render_block_data, render_block_context (Attempt #2)#765noisysocks wants to merge 1 commit intoWordPress:masterfrom
Conversation
|
@azaozz @TimothyBJacobs: How about something like this? Properties can still be lazily initialised, but it requires explicitly passing an option to |
Move the pre_render_block, render_block_data, and render_block_context filters from render_block() to WP_Block. This ensures that they are called for all blocks, including nested blocks, not just top-level blocks. So that there is no performance penalty incurred from calculating block properties twice, WP_Block can now be made to not set any derived block properties until render() is called.
045f824 to
de7aec3
Compare
| array( | ||
| 'filter_data' => true, | ||
| ) | ||
| ); |
There was a problem hiding this comment.
Potentially these could be combined into one setting?
$block = new WP_Block(
$parsed_block,
$context,
WP_Block_Type_Registry::get_instance(),
array(
'filter_on_render' => true,
)
);
assert( ! isset( $block->name ) ); // Because `filter_on_render` was provided
$rendered_block = $block->render();
assert( isset( $block->name ) ); // Because `render()` was called| global $post; | ||
|
|
||
| /** This filter is documented in wp-includes/blocks.php */ | ||
| $pre_render = apply_filters( 'pre_render_block', null, $this->parsed_block ); |
There was a problem hiding this comment.
I notice this is still defined in render_block and not removed like render_block_data and render_block_context.
There was a problem hiding this comment.
My intention was that calling it twice would let one short-circuit render_block and WP_Block::render. Now that I think about it, though, maybe that will cause unexpected results for folks using pre_render_block for things other than return false;.
peterwilsoncc
left a comment
There was a problem hiding this comment.
A few minor notes but still getting my head around it.
| * @var array | ||
| */ | ||
| public $inner_content = array(); | ||
| public $inner_content; |
There was a problem hiding this comment.
I am wondering if changing the default type could lead to back-compat problems. null is still falsey but if a plugin is doing strict type checking then it might be problematic.
Once set, can any of these values be an empty() value?
Maintaining the __get() could solve this problem.
There was a problem hiding this comment.
There shouldn't be any compatibility problems here because all of the attributes are initialised in WP_Block::__construct() by default. The only change in behaviour is if 'is_eager' => false is provided.
| public function __construct( $parsed_block, $available_context = array(), $registry = null, $options = null ) { | ||
| $options = wp_parse_args( | ||
| $options, | ||
| array( | ||
| 'is_eager' => true, | ||
| ) | ||
| ); | ||
|
|
||
| $this->parsed_block = $parsed_block; | ||
| $this->available_context = $available_context; | ||
| $this->registry = $registry ? $registry : WP_Block_Type_Registry::get_instance(); | ||
| $this->options = $options; | ||
|
|
||
| if ( $this->options['is_eager'] ) { | ||
| $this->set_derived_properties(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Nit: $args instead of $options for consistency with the majority of the code base.
There was a problem hiding this comment.
Hm, I was trying to be consistent with WP_Block::render() which already has $options. Reckon I should change both? Or just the constructor's? Or neither?
| $rendered_content .= $block->render( array( 'filter_data' => true ) ); | ||
| } | ||
|
|
||
| remove_filter( 'render_block_context', array( $this, 'filter_render_block_context' ) ); |
There was a problem hiding this comment.
Nit: No need to remove filters/actions in the test, they're reset after each test as part of the default tearDown().
There was a problem hiding this comment.
Oh cool! Is it better to be explicit though?
| $parsed_blocks = parse_blocks( '<!-- wp:outer --><!-- wp:skip /--> How are you?<!-- /wp:outer -->' ); | ||
| $parsed_block = $parsed_blocks[0]; | ||
| $context = array(); | ||
| $block = new WP_Block( $parsed_block, $context, $this->registry ); |
There was a problem hiding this comment.
Additional tests to ensure lazy mode works would be dandy.
|
Neither works for me.
On reread it goes in to an options property so best as is.
|
|
Thinking now is the best time to look a bit at the "bigger picture" :) As far as I see
Uh, sorry this is getting too long. As far as I see there's no clarity about how |
|
I don't really have much to add that I haven't mentioned on the ticket yet. I think this is a fine approach, though I personally would prefer it followed a pattern closer to our existing patterns using |
Move the pre_render_block, render_block_data, and render_block_context filters from render_block() to WP_Block. This ensures that they are called for all blocks, including nested blocks, not just top-level blocks.
So that there is no performance penalty incurred from calculating block properties twice, WP_Block can now be made to not set any derived block properties until render() is called.
Trac ticket: https://core.trac.wordpress.org/ticket/51612
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.