Description
openedon Jan 15, 2020
The Problem
A lot of patterns have surfaced where we need inner blocks to be aware of specific values configured on their parents.
For example, the Post block needs to set a post ID context value for a Post Title block child.
This introspection is hard to do because rendering happens depth-first, so child render-callbacks run before their parents run theirs. Blocks like the navigation block get around this by rendering their children themselves.
Imagine having a 3 level pyramid of blocks implementing this pattern:
1A
/--\
/- -\
-- --
2A 2B
/-|-\
/- | -\
-- | --
3A 3B 3C
The callbacks would run in the following order:
3A
3B
3C
2A
+3A
+3B
+3C
2B
1A
+3A
+3B
+3C
+2A
+3A
+3B
+3C
+2B
The +
signs represent the extra re-renders caused by this pattern. The approach converted this linear computation into something that scales with the square of the number of levels times the average number of children per node?
A Solution
I propose an alternative way for parents to provide data to their children during server-side rendering. It would require minimal changes to Core, and it fits in nicely with our heavy client-side usage of React Context.
Basically, we should extend render_block
so that it's last parameter is a union of its parents' attributes:
render_block( $block['innerBlocks'][ $index++ ], $parent_attributes . $block['attrs'] )
This approach would allow blocks like Post Title to check for the nearest parent provided post ID easily, and the Navigation Link block to access the provided class name and style attributes so that they can render themselves correctly.