-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
render_block_context
another approach that solve the context issue
#7522
base: trunk
Are you sure you want to change the base?
render_block_context
another approach that solve the context issue
#7522
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
@mukeshpanchal27 Heads up that the tests in #7344 have been updated to reflect the last few comments there. |
Nice one @mukeshpanchal27. @dlh01 and @joemcgill, it looks like all the unit tests we could think of pass in this branch. How do you feel about the proposed solution? Is it good enough to move forward as part of the WP 6.7 release? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mukeshpanchal27 This looks very promising. Mostly questions from my end, to make sure I understand this correctly.
Thanks for the ping! I should be able to take a look at this Wednesday or Thursday. |
render_block_context
another approachrender_block_context
another approach that solve the context issue
The PR is ready for review. Address the feedbacks. |
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN:
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
I take another pass and try to find the the solution to not merge the |
@felixarntz @joemcgill @dlh01 @gziolo In c83ca82, I removed the context merging from Currently, there’s only one uncovered case: when a block needs context for itself, not for nested blocks. The In the single block case, the Would it be acceptable to remove the failing unit test and merge this PR, as it resolves the ancestor block context issue? We can then open a follow-up discussion to address the remaining part. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mukeshpanchal27 This looks almost there for me, just one note.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mukeshpanchal27 This looks solid. Regarding your comment #7522 (comment), sharing my thoughts here.
TL;DR: The main problem we still need to address is that render_block_context
effectively filters a block's $context
for inner blocks, but a block's $available_context
for top-level blocks.
First of all, there's definitely some inconsistency today between the filter application, which is part of the problem:
- In
WP_Block::render()
, therender_block_data
andrender_block_context
filters are applied after the block has been instantiated. - In
render_block
however the two filters apply before the block is instantiated, leading to different behavior that causes the test to fail.
So far, so good. I think the test_render_block_context_allowed_context()
test may not be entirely right in what it tests though, since we also shouldn't ignore the uses_context
property of a block. Not all available_context
should also be the context
for the block. Only available_context
that is also in uses_context
for the block should be part of the block's actual context
. So I think the test failure in line 301 is expected and in fact correct, since you restrict the block type to only use "example", so "arbitrary" shouldn't be used.
That leads me to the other problem though that still exists: Since in WP_Block::render()
the filtered $context
is used in the inner block directly, it does not respect that block's uses_context
property anymore.
Basically, it's not clear what render_block_context
is exactly supposed to filter:
- Is it supposed to filter the block's
$context
, explicitly allowing to ignore whatever the block'suses_context
property says? That's what it's doing for inner blocks today.- If so, then discard my previous statement, and we need to fix this for how it works on the top-level block so that your test
test_render_block_context_allowed_context()
passes. For example, set the$context
property on the block instance directly to the filtered value.
- If so, then discard my previous statement, and we need to fix this for how it works on the top-level block so that your test
- Is it actually supposed to filter the
$available_context
? On the top-level block, that's what it's doing today.- If so, we need to fix the
refresh_context_dependents()
method so that it sanitizes$context
to still only contain what the block'suses_context
allows for.$available_context
should still include anything including arbitrary values.
- If so, we need to fix the
@felixarntz I wanted to make sure you saw this older conversation in the other PR about this topic, where @gziolo mentioned that at least some of the time, the filter is meant to override |
@dlh01 Thank you for providing this context. In that case, I would argue we should adjust how this is handled in This way, it should behave consistently going forward, with the filter allowing to override |
Existing usage of wordpress-develop/src/wp-includes/block-template.php Lines 311 to 324 in dec5c90
wordpress-develop/src/wp-includes/blocks/block.php Lines 76 to 90 in dec5c90
wordpress-develop/src/wp-includes/blocks/comment-template.php Lines 29 to 50 in dec5c90
wordpress-develop/src/wp-includes/blocks/post-template.php Lines 101 to 123 in dec5c90
My understanding of how it should work is as follows:
In practical terms, it means that wordpress-develop/src/wp-includes/class-wp-block.php Lines 52 to 59 in dec5c90
It's the property that gets impacted by the It gets filtered by scanning Now diving into the code again, to see how it fits into the model based on my last assessment. Let's start with wordpress-develop/src/wp-includes/blocks.php Lines 2110 to 2114 in a78540b
In this case, it might be helpful to rename Let's move now to wordpress-develop/src/wp-includes/class-wp-block.php Lines 491 to 499 in a78540b
This part doesn't fit the model I illustrated above. The changes from the filter get applied to the derived context of the child block. In practice, it means that any property can be exposed to this block even if it wasn't list inside |
In #7522 (comment) I shared the way I was always thinking about block context and related filters. Now, let's go with the most realistic approach which is tied to the current implementation. In practice, the contract established with |
For the sake of the experiment, I played a bit with changes that try to aggressively run the same hook to update both the available context and the context: Index: src/wp-includes/blocks.php
===================================================================
--- src/wp-includes/blocks.php (revision 59420)
+++ src/wp-includes/blocks.php (working copy)
@@ -2163,6 +2163,8 @@
$context['postType'] = $post->post_type;
}
+ $block = new WP_Block( $parsed_block, $context );
+
/**
* Filters the default context provided to a rendered block.
*
@@ -2183,10 +2185,8 @@
* }
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
*/
- $context = apply_filters( 'render_block_context', $context, $parsed_block, $parent_block );
+ $block->context = apply_filters( 'render_block_context', $block->context, $block->parsed_block, $parent_block );
- $block = new WP_Block( $parsed_block, $context );
-
return $block->render();
}
Index: src/wp-includes/class-wp-block.php
===================================================================
--- src/wp-includes/class-wp-block.php (revision 59420)
+++ src/wp-includes/class-wp-block.php (working copy)
@@ -138,7 +138,8 @@
$this->block_type = $registry->get_registered( $this->name );
- $this->available_context = $available_context;
+ /** This filter is documented in wp-includes/blocks.php */
+ $this->available_context = apply_filters( 'render_block_context', $available_context, $this->parsed_block, null );
if ( ! empty( $this->block_type->uses_context ) ) {
foreach ( $this->block_type->uses_context as $context_name ) { I passed |
@gziolo I think I understand most of your exploration, but not your conclusion of how it should behave. Sharing my understanding and asking for clarification:
|
I'm not surprised as it's a very complex problem to tackle as we have an important backward compatibility problem to solve. I offered my preferred solution in #7522 (comment) (that might require some deprecation, phase out for current behavior, detailed dev note), and an alternative (#7522 (comment)) that should work in most cases (the dev note might be sufficient). We should pick one.
Again, I'm open to the idea of applying the changes you proposed. I only wanted to emphasize again it's hard to predict what that would cause as a side effect. In some cases, inner block during rendering might depend on the presence of the context that isn't explicitly exposed through Anyone from @WordPress/gutenberg-core willing to chime in and share their opinions on this topic that will help to make the final decision? |
@gziolo Regarding backward compatibility, I assume you're referring to plugins that may potentially access a block's We could potentially still fix the behavior to get to the preferred state, but have a deprecation strategy to not break such behavior right away. Something like:
WDYT? |
Yes, that’s exactly what I was thinking about in terms of backward compatibility. It seems like a viable path forward. We can explore specific details of the depreciation strategy separately later. I was thinking also about making the context a virtual property and handle everything through magic methods. Whatever works best here 😀 |
That was my first thought too, but I think that wouldn't work because magic methods would only be called for the entire |
I think got it know, we would pass |
That's actually not entirely what I thought, but that's even better than what I thought 😆 So let's try that. |
@gziolo and @felixarntz, I've been spending time today catching up on this conversation and wanted to summarize what I understand to be the current thinking. Based on what @gziolo said is his preferred solution, the Conceptually, this makes sense to me, and I think could be achieved by filtering the In practice, however, the I've put together the following visual to help illustrate the concept of block context as it currently exists: Restating what is in the illustration:
If applying the filter to
Whether or not we then change the current ability for a block's |
Thanks for the helpful summary and visualization @joemcgill. It makes sense for now to focus on only addressing the bug that As far as I can tell, to fix that this PR is almost there. It would be great to get your code review as well based on your understanding. |
@joemcgill, thank you for your analysis to this complex problem. I agree with the proposed path forward, where the focus moves on solving one problem at a time. In effect, we seem to have a path forward to land this PR after addressing the feedback continued by @felixarntz. I'm happy to have another look from that angle next week. |
@felixarntz I have addressed the recent feedback and PR is ready for review.
@gziolo Happy to get your feedback if you have moments. Thanks. |
Trac ticket: https://core.trac.wordpress.org/ticket/62046
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.