-
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
Block Hooks API: Consolidate approach to get all hooked blocks #6584
base: trunk
Are you sure you want to change the base?
Block Hooks API: Consolidate approach to get all hooked blocks #6584
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. |
I think this approach (i.e. the newly introduced function) makes sense 👍 |
$hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) | ||
? $hooked_blocks[ $anchor_block_type ][ $relative_position ] | ||
function maybe_has_hooked_blocks() { | ||
$hooked_blocks = get_hooked_blocks(); |
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.
get_hooked_blocks()
is now run here and inside get_hooked_blocks_by_anchor_block
which is executed on every block traversal. I think we need to figure out a way to either avoid this, or a caching strategy around it.
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.
In this commit (6bdec1e) I have memoized the result of get_hooked_blocks()
. The cache will persist per-request which means we won't be degrading performance when comparing it to how it currently works but would like a second opinion on this for further opportunities for improvements.
$anchor_block_type = $parsed_anchor_block['blockName']; | ||
$hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) | ||
? $hooked_blocks[ $anchor_block_type ][ $relative_position ] | ||
function maybe_has_hooked_blocks() { |
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.
Open to a better function name but intentionally used maybe_
to signal that even though the filter could be used it still may result in no hooked blocks.
$blocks = parse_blocks( $template->content ); | ||
$template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); |
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.
_build_block_template_result_from_post
has these lines inside the conditional above it. Is there a reason we aren't doing the same here?
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.
If memory serves, it's because we need to inject the theme
attribute into template parts (and set it to the currently active theme) when first loading a template part from a file. For better or worse, that logic ended up in make_before_block_visitor
.
Now the need for that attribute is of course unrelated to the presence of hooked blocks -- it needs to be injected unconditionally 😬
(I'd be curious if we have test coverage at that level, i.e. if a test would start failing if we moved these lines into the conditional.)
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. |
* @param WP_Block_Template|WP_Post|array $context The block template, template part, or pattern that the anchor block belongs to. | ||
* @return string Empty string. | ||
*/ | ||
function set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_position, $hooked_blocks, $context ) { |
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.
I'm afraid we cannot change the function signature like that 😕 (When it comes to back-compat in WordPress, think of the @access private
as mostly ornamental 😬)
We might be able to deprecate the argument (like we did here). (We'll need to check if that's possible in a case like this, since it's not the last argument of the function.)
The same also applies to some other functions touched by this PR, e.g. make_before_block_visitor
and make_after_block_visitor
, insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata
, etc.
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.
😢 I suspected this might be the case, but hoped it wasn't. As we've discussed privately in DM there is precedent for deprecating non-last args
function wp_install( $blog_title, $user_name, $user_email, $is_public, $deprecated = '', $user_password = '', $language = '' ) { |
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.
@ockham I believe this is ready for rereview 🙏🏻 |
I'll rebase. |
d2be9cf
to
86a3f2e
Compare
86a3f2e
to
e5135d1
Compare
The major problem to solve here is performance. FWIW, At the time, we decided against caching the result of (Generally, people were skeptical about caching things that are depending on registered blocks, as that had turned out tricky in the past.) For the above reasons, I'm a bit skeptical about caching inside of |
Interesting, I wasn't aware of the background here so appreciate you providing that additional context for me. I didn't experience this in my testing but that's not to say it's not an issue at all, just an issue that didn't surface itself to me yet.
Hmm, interesting. I'll have a further think and potentially revisit this improvement but I can see how you're thinking about this solution. |
Our current approach to getting hooked blocks has two parts to it:
We use
get_hooked_blocks()
to get all of the hooked blocks which are hooked from theblock.json
file.In function
insert_hooked_blocks
we apply the filter callbacks (passing a derived value from step 1 as the default value) to get hooked blocks that are applied by thehooked_block_types
filter.Currently it's a bit confusing and without knowledge you'd assume
get_hooked_blocks()
would retrieve all of the hooked blocks. Additionally it feels like you have to run a few different pieces of code separately and combine their resulting values to get a complete picture which could result in some bugs or unnecessary complexities.This PR aims to fix that by creating a single function to get hooked blocks based on anchor block and position.
Note: As a result of this refactor it has meant executing
get_hooked_blocks()
multiple times in the lifecycle of a request, to prevent any performance degradation I've memoized the result of the function but would appreciate a second opinion on this.Trac ticket: https://core.trac.wordpress.org/ticket/60769
Related WordPress/gutenberg#62658
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.