#59882 closed defect (bug) (fixed)
Expose serialized template content to callbacks registered to the `hooked_block_types` filter.
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 6.4.2 | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Editor | Keywords: | has-patch fixed-major commit |
| Focuses: | template | Cc: |
Description
The recently introduced Block Hooks API exposes a filter (hooked_block_types) which exposes $context as an argument. When a template file is built, WP_Block_Template::content is not exposed to the callbacks registered on hooked_block_types.
This would be useful for callbacks that might want to detect the presence of a serialized block instance (or potentially in the future utilize the HTML API) to restrict where the block is injected (before the template is rendered).
Addressing this would also achieve parity with the structure of $context when it represents a pattern (where pattern serialized content is present).
Change History (14)
This ticket was mentioned in PR #5656 on WordPress/wordpress-develop by nerrad.
2 years ago
#1
- Keywords has-patch added; needs-patch removed
@Bernhard Reiter commented on PR #5656:
2 years ago
#2
Makes sense, thank you for your contribution!
If we do this, should we also drop the $template_content variable altogether? It's currently parsed for the actual hooked blocks insertion; it might be less confusing for people if we changed that to also used $template->content.
2 years ago
#4
One thing to be aware of with this change is that it might appear to extenders that it's possible to mutate $template->content. The blocks are already parsed from content by this point but one extension mutating the property could mess it up for every other callback utilizing block_hooks and checking this property (the content wouldn't match the rendered blocks). Ideally, $template->content would be a private property exposed via getter so that extenders can't mutate it.
@Bernhard Reiter commented on PR #5656:
2 years ago
#5
Yeah, good point 🤔
Just to make sure, are you still okay if we proceed (with https://github.com/WordPress/wordpress-develop/pull/5656/commits/9eebbbed451cd63ac52f3a04ad52dfd5df6a3b20)? Personally, I'm inclined to say that it's okay to expect an extender _not_ to mess up $template->content, or at least I don't think it's a blocker.
Also agree that a getter would be nice to have for the template content, but OTOH, we're also overriding it with new markup returned from `traverse_and_serialize_blocks` (with hooked blocks inserted) so I'm not sure we can make the content property private, as PHP doesn't seem to have a `friend` concept like C++ does 🤔
Anyway, mostly just curious if you think this PR is blocked by any of the above 😄
2 years ago
#6
Yup, I'm okay with the latest commit. I just wanted to flag it as a potential issue to get further thoughts. The only way (I can currently think of) that we'd be able to lock this down is to require a new object constructed and use something the value object pattern to keep WP_Block_Template immutable. Practically, I'm not sure how big of a deal that is.
#7
@
2 years ago
- Milestone changed from Awaiting Review to 6.4.2
- Owner set to Bernhard Reiter
- Status changed from new to accepted
@Bernhard Reiter commented on PR #5656:
2 years ago
#10
I've taken the liberty of moving the line and committed this change to Core: https://core.trac.wordpress.org/changeset/57118.
Hope that's okay! 😊
#11
@
2 years ago
- Keywords fixed-major commit added
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening for backporting to the 6.4 branch.
@Bernhard Reiter commented on PR #5656:
2 years ago
#13
Backported to the 6.4 branch in https://core.trac.wordpress.org/changeset/57119.
When building the template, initialize WP_Block_Template with the serialized block content so callbacks registered to the
hooked_block_typesfilter can access the content.If you registered a callback to
hooked_block_typeswhen the callback receives an instance of a template or template_part via the$contextargument, the$contentproperty will be null. Minimally reproducible example:In the above example, the code is checking to see if the
$contextis an instance ofWP_Block_Templateand if it is, looks in the$contentproperty for the serialized representation of thecore/post-titleblock. If it's present, then bail early and don't inject navigation. For the pages template, I'd _expect_ this to not injectcore/navigationbecause thecore/post-titleblock is present in the content, but in fact, it does get injected becauseWP_Block_Template::$content === null.Screenshots:
Trac ticket: https://core.trac.wordpress.org/ticket/59882