[wp-trac] [WordPress Trac] #49442: Request: filter for parse_blocks() result

WordPress Trac noreply at wordpress.org
Mon Jun 16 19:48:14 UTC 2025


#49442: Request: filter for parse_blocks() result
---------------------------------------+---------------------
 Reporter:  dougwollison               |       Owner:  (none)
     Type:  feature request            |      Status:  new
 Priority:  normal                     |   Milestone:  6.9
Component:  General                    |     Version:  5.0
 Severity:  normal                     |  Resolution:
 Keywords:  has-patch needs-test-info  |     Focuses:
---------------------------------------+---------------------

Comment (by dmsnell):

 Thanks for sharing the mind dump @justlevine — all good, it’s okay for
 things to take time, especially design-oriented things since the
 repercussions of a design carry far longer than the effort spent building
 them.

 > that really needs to come from improvements to WP_Block_Parser::parse(),
 which might be beyond the scope or might be enough for us to infer from
 pre_render_block hook

 there very well could be need to improve the parser’s docblocks with
 examples and outputs. still, this is more important to me if adding a
 `parse_blocks` filter than it is in the parser itself, because someone
 implementing a different parser is more likely to investigate, while
 someone reaching for a filter with `array` is likely going to assume that
 the situation is as simple as the name and documentation suggest it is

 but we know it’s not that simple, and characteristically different than
 `pre_render_block`. all of the existing filters have intentionally focused
 on the block level, leaving //traversal// up to WordPress itself. this
 proposed filter is introducing an interface which leaves traversal up to
 the plugin author when I don’t think there’s precedent in Core of doing
 so.

 that is, if we introduce this new way of traversal, we owe it to the
 ecosystem to highlight how basic assumptions will be broken and how to
 avoid falling into those pits.

 although I shared many words here the proposal is neither lengthy nor
 complicated: at a minimum we could list of edge cases in `Example`
 sections of the filter’s docblock and leave WARNING notes that the blocks
 are a tree and require tree traversal.

 > why (to my understanding) traverse_and_serialize_blocks() doesn't help
 here, because it's even _more removed_ from the parse/render knot I'm
 hoping to decouple

 this makes sense, and I wondered if that was where you were going. in such
 a case let’s focus on establishing the motivating use case for all this.
 `parse_blocks()` is universal in WordPress and changing its behavior is
 going to bring potential risks in a lot of unexpected places, even if that
 change comes from a plugin.

 this is where I am curious about enforcing constraints on certain post
 types, as perhaps there are other ideas for exposing extensibility points
 later in the flow from database to browser, or content-type-specific
 extension points which are guaranteed to be limited by nature instead of
 expansive by nature.

 > even if the existing project tech debt unfortunately forces it to act on
 the array<TRenderBlockArgs>, instead of the array of $args for a single
 block.

 when you get around to it, I would love to understand better what you mean
 here. I do not think I follow what you are trying to say.

 > feel the need to rely on weird caching solutions to make getting the
 block data more performant

 for sure, almost every time I see caching introduced it’s usually due to a
 felt need to rely on weird caching solutions. transparently, this only
 makes me more curious when I hear caching proposals. block parsing is
 quite fast, much faster than almost every other step of the block
 rendering pipeline, and I have yet to seen empirical evidence showing
 caching the parse to have any meaningful impact. if we want to talk about
 memory bloat that’s definitely an issue, but one that caching only
 exacerbates.

 > we need to separate the act of rendering blocks from the act of
 hydrating block-data from parsable-strings

 perhaps we can focus on fleshing out what you mean here, as I think it
 probably makes more sense to you when you write it in the context of the
 work you’ve been doing than it does to me when I read it and am trying
 trying to guess what you mean.

 where I was going with `traverse_and_serialize_blocks()` is another effort
 in Core to build semantic tools for operating on block trees. perhaps
 there are similarly-easy-to-add-and-similarly-impossible-to-remove filters
 or stages that help you accomplish what you want more easily than exposing
 the list of parsed blocks. I don’t know. I’m not opposing this work, but I
 don’t quite understand it.

 > Pick a popular extends WP_Block_Parser and show what's required as a
 plugin to safely add your custom block attribute to support it + core
 blocks.

 Noting that on the
 [https://wpdirectory.net/search/01JXX30XA8V5M6TVE29YW3TMZQ WPDirectory]
 there are three plugins extending `WP_Block_Parser`. of those, hCaptcha is
 actually using it for its intended purpose, where they supplement failed
 parses with some additional best-effort parsing. Shout out to them! The
 other two both appear to extend the block parser and introduce a few
 additional layers of complexity when it //seems// to me like a more basic
 `render_block` filter would serve the purposes in a much easier way. One
 has a number of stages of transforming the parser output, and every one of
 them demonstrates the nuanced issues I mentioned above, and this is no
 critique to them. If capable teams with huge plugin install bases overlook
 some of these details, then making it even more normative to use such an
 interface increases my skeptical intuition on this.

 > IIRC there were some REST APIs headed to core/gutenberg too that (as
 proposed) have no choice but to needlessly render too.

 This is a misunderstand I suppose we could support more. It should be
 trivial to skip all rendering, either by calling `parse_blocks()` directly
 or by one of my favorite methods: the `pre_render_block` filter

 {{{#!php
 <?php
 define( FIRST_PRIORITY, /* whatever you typically use */ PHP_INT_MIN );

 function my_block_thingamajig( $content, $parsed_block, $parent_block ) {
         // do something with block
         // visits parents before children, children before siblings
         // can rely on static vars or globals for output, or return actual
 output (e.g. arrays, JSON) through $content
         // top-level blocks have `null` as a parent block

         return asset( $parent_block ) ? '' : null;
 }

 add_filter( 'pre_render_block', 'my_block_thingamajig', FIRST_PRIORITY, 3
 );

 do_blocks();

 remove_filter( 'pre_render_block', 'my_block_thingamajig' );
 }}}

 Please don’t feel obliged to rapidly reply. It’s worth taking time to
 ponder, refine, and write out stuff. Wishing peace amidst the hectic
 times.

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


More information about the wp-trac mailing list