-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Add optional callback argument to serialize_block(s) #5187
Conversation
Hi! Please forgive my dropping in with a few comments, but this PR was interesting to me. As a regular reader of the block API, I found the Next, after thinking about the variable name, I wondered why this function would introduce a dedicated parameter for what most other functions would make accessible as a filter — Still, I can think of some reasons against a filter, such as being wary about adding a filter to a hot code path, a desire to keep the new behavior in #5158 "private," or disliking the pattern of adding and removing one-off filters. So that leads to my final thought, which is, rather than add a callback to
This new function could be Regardless, a new function would keep an added responsibility out of Thanks for considering it! |
@dlh01, you shared great feedback in your comment about
This would work, but that would require traversing the tree of blocks twice. You would essentially have to recreate recursion inside
Yes, that would definitely be my favorite approach. I'm very hesitant to go this path though, as it's hard to predict the consequences. In this case, it's safer to start small and allow modifications only when loading the templates and patterns from the files on the server, as we know it will get processed only once. In fact, Block Hooks feature will most likely include a filter as part of the flow so plugin devs can cover more advanced use cases where they have specific limitations for automatically inserting blocks. Anyway, let's keep the discussion going as we implement the basic functionality to enable the feature for WP 6.4 beta 1. |
Hey @dlh01, thanks a lot for your thoughtful feedback! I think you're making a number of great points there, so it's much appreciated 😄
Yeah, I found the naming part hard. Eventually, I went with the fairly generic I'm a bit reluctant to use
Yes, that was pretty much my thought process! I'll add that the main reason against a filter was that
I also considered this option 😅 but ultimately decided against. Two reasons here:
FWIW, I was considering still some other alternatives/variations (e.g. even re-implementing With all that said, I could see us adding a generic filter to Edit: I only saw that @gziolo already replied to a similar effect after I submitted my comment 😅 |
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.
This looks good. We still might want to improve the part related to how the new $callback
param is called, or exercise a different pattern for fulfilling the same task as discussed in the comments. Let's ensure it doesn't delay the process of integration the Block Hooks into WP 6.4 beta 1.
Thank you @gziolo! I'll make one minor change to the PHPDoc for |
Committed to Core in https://core.trac.wordpress.org/changeset/56557/. |
Thanks @ockham and @gziolo for your comments! (And thanks @ockham for the generous props.) Both of you are right, of course, that a separate function would require traversing the block tree again, which is not optimal. I would say in response, first, that a separate function leaves the door open to refactoring the logic in both functions to reduce the duplication with minimal effects on backwards compatibility. Second, the performance effect of traversing the tree twice would be felt in only the locations where the new function was called, whereas the current implementation commits core to checking |
But if it needs serialization in addition to another operation, it will always traverse the tree at least twice, won't it? I'd really rather avoid that as a lower boundary for file-based template processing, when it's clear that it is avoidable.
That's fair enough (although my hunch is that I believe that it should be easy enough to optimize the chosen approach: If the function serialize_blocks( $blocks, $callback = null ) {
$result = '';
if ( is_callable( $callback ) ) {
foreach ( $blocks as $block ) {
$result .= serialize_block( $block, $callback );
};
} else {
$result .= _serialize_block_without_callback( $block );
}
return $result;
} With |
I checked out of the curiosity whether this change impacted performance metrics reported in It gets compensated with the further refactoring as documented in #5192 (comment). |
I think you sort of answered your own question 😄 Traversing the tree twice is definitely avoidable. In my original comment, I suggested a separate function to apply the callback throughout the tree before serialization occurs. Another way of achieving the goal of minimizing the impact to Both new functions would, though, put us back to where we started, which is that the logic to recurse through the tree would be recreated. I think at the heart of my original comment was the sense that it would be preferable to accept that duplicated logic in a new function that served the specific purposes presented by block hooks, compared to permanently encoding it in the main A new internal function can be deprecated and forgotten as the block API takes on new use cases (for example, if it becomes necessary to merge multiple operations into a traversal), but the new arguments to the existing functions will live on. Anyway: This is fun to talk about, but I know you have other things to work on, so we can leave it here. I appreciate you indulging me in this discussion and will be happy to talk about it more if it ever comes up again! |
@dlh01 Just a quick update: Since we need to add a bit more logic, we'll be reverting the change to |
Very interesting, @ockham — thanks for the heads up! On the subject of sharing code between the functions, the decorator pattern might become helpful as the block API evolves. Here's an example implementation that I was experimenting with after our initial discussion, based on the original changes to |
For some operations, we need to traverse the parsed block tree (before it is eventually serialized). In order to minimize the number of tree traversals (which is a potentially costly operation), it seems that adding a callback function argument to
serialize_block()
-- which inevitably has to traverse the entire tree anyway -- is a natural fit.Examples where this could come in handy:
theme
arg injection into a block template loaded from a file.Spun off from #5158.
Trac ticket: https://core.trac.wordpress.org/ticket/59327
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.