[wp-trac] [WordPress Trac] #62046: `render_block_context` filter works differently on top-level vs. inner blocks

WordPress Trac noreply at wordpress.org
Mon Sep 16 18:17:56 UTC 2024


#62046: `render_block_context` filter works differently on top-level vs. inner
blocks
----------------------------+------------------------------
 Reporter:  dlh             |       Owner:  (none)
     Type:  defect (bug)    |      Status:  new
 Priority:  normal          |   Milestone:  Awaiting Review
Component:  Editor          |     Version:  5.9
 Severity:  normal          |  Resolution:
 Keywords:  has-unit-tests  |     Focuses:
----------------------------+------------------------------

Comment (by obliviousharmony):

 How well timed, I ''just'' debugged this same problem lol. I'm working on
 [https://github.com/woocommerce/woocommerce/pull/51390 a PR refactoring
 how we're passing dynamic context] in some of our blocks and ran into it.
 I've spent the better part of my weekend digging through all of the
 rendering logic for blocks and I've got a possible idea.

 I'm sure there are reasons related to how inner blocks initially
 developed, however, It's a little weird that we make a distinction between
 a top-level block and an inner-block with respect to rendering. I think we
 should use `render_block()` for both inner and top-level blocks so that we
 can keep all of the hooks together. As for the problem itself, the caveat
 here is that the available context is only populated on `__construct` and
 there's no filtering before that point.

 My first thought is to move `render_block_data` and `render_block_context`
 into the constructor but I think this might be a breaking change since it
 moves these filters to a different stage of the block rendering pipeline.
 Anyone relying on this being called between `pre_render_block` and
 `render_block` will be in for a shock. In my case, for example, I'm using
 `pre_render_block` to set the global post and then a low-priority
 `render_block` callback to reset it. While this change doesn't impact me,
 I'm very close conceptually to changing something that is then expected to
 be use as context.

 My second thought is that, technically, none of these hooks require the
 block instance to exist. They operate on the `$parsed_block` array that is
 then passed to the `WP_Block` constructor. The caveat here is that
 `WP_Block_List` handles our instantiation and it does so using
 `offsetGet`. Anyone relying on this behavior before `WP_Block::render()`
 instantiates it will still need that functional block instance.

 My third thought is that, since `WP_Block_List` holds onto the available
 context before the blocks are instantiated, we would need some way to
 filter it there to alter the context being given to the block.

 ----

 The way that we're instantiating the block essentially forces either a
 breaking change or new filters. As much as I'd ''love'' to move these
 filters into the constructor, I think they have surrounded the block's
 `render()` behavior for too long to be safe to touch. I propose this:

 - New Filter: `create_block_available_context`: This filter goes in
 `__construct()` and allows developers to filter the context available to
 the block.
 - New Filter: `create_block_data`: This filter also goes in
 `__construct()` and filters the `$parsed_block` it is given.
 - Add `$parent_block` as an optional parameter to
 `WP_Block::__construct()` so that it can be available to the above
 filters.
 - Move the `$postId` and `$postType` injection from `render_block` into a
 `create_block_available_context` hook and inject it if it's not already
 set.
   - This should be safe because `render_block_context` would still receive
 these without any knowledge of where they came from. Even if someone was
 filtering to change them, since it's set on construction (and they can't
 currently alter that behavior), their code would continue to work.
   - There's a small breaking change here since right now you can filer
 this to remove those from the block hierarchy. I don't know why you would
 do that though and it would probably break **everything**?

 Technically we documented `render_block_context` as filtering the
 ''default'' context. There's a meaningful distinction between filtering
 the rendered context and the context provided to a block hierarchically.
 These changes should allow is to provide dynamic context options while
 still being able to override the context at render time.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/62046#comment:6>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list