Editor: Do not apply Block Hooks when generating post excerpts. - #13524
MarcinDudekDev wants to merge 3 commits into
Conversation
wp_trim_excerpt() builds the excerpt from already-rendered content: it runs excerpt_remove_blocks() and temporarily unhooks do_blocks() and wp_filter_content_tags() so the excerpt is not processed a second time. The Block Hooks callback apply_block_hooks_to_content_from_post_object(), added to 'the_content' at priority 8 in [59523], was never unhooked there and still runs during excerpt generation. The callback wraps the content in a temporary core/post-content wrapper block, which anchors first/last-child hooked blocks even when no block delimiters remain. Those blocks can never render, because do_blocks() is unhooked, and any markup they carry via the 'hooked_block' filter leaks into the excerpt text as plain text. The callback also resolves its context from the current loop post rather than the post being excerpted. Unhook and restore it alongside the existing do_blocks()/wp_filter_content_tags() dance, matching the same unhook already performed in insert_hooked_blocks_into_rest_response(). Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
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. |
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. |
westonruter
left a comment
There was a problem hiding this comment.
This looks good to me. However, I will request a review from @ockham since he introduced this function to begin with.
What / why
Since r59523 (Core-61074, WP 6.8),
the_contentcarries a Block Hooks callback at priority 8 —apply_block_hooks_to_content, swapped forapply_block_hooks_to_content_from_post_objectin r59838 (Core-61074, Core-62716).
wp_trim_excerpt()already unhooksdo_blocks(r56560 / Core-58682and
wp_filter_content_tags(r55850 / Core-56588) around its innerapply_filters( 'the_content' )call, but the priority-8 callback was never unhooked. Three consequences:
temporary
core/post-contentwrapper block sofirst_child/last_childhooked blocks havean anchor; the algorithm serializes them into the content,
do_blocksis unhooked so they cannever render, and
wp_strip_all_tags()strips the `` delimiters — leaving the markup ahooked block carries via the
hooked_blockfilter as literal excerpt text.Reproduced: excerpt goes from `'Visible text.'` to `'Visible text. LEAKED HOOKED TEXT'`.
parse_blocks()traversal,get_hooked_blocks(), thehooked_block_types/hooked_blockfilters, and a_wp_ignored_hooked_blocksmeta read onevery generated excerpt, for output that can never be visible.
get_post()(current loop post),not the post passed to
wp_trim_excerpt(), so off-loop excerpts read the wrong post's_wp_ignored_hooked_blockssuppression.The change
Unhook and conditionally restore
apply_block_hooks_to_content_from_post_object(priority 8)inside
wp_trim_excerpt(), mirroring the existingdo_blocks/wp_filter_content_tagsdance andthe identical unhook core already performs in
insert_hooked_blocks_into_rest_response()(blocks.php:1559-1573). A site that deliberately unhooked the callback is left unchanged.
Testing
tests/phpunit/tests/formatting/wpTrimExcerpt.php: callback unhookedduring the inner
the_contentrun; restored afterwards; not resurrected when previouslyunhooked; Block Hooks algorithm does not run (spied via
hooked_block_types, which only firesinside the algorithm); hooked-block markup does not leak into the excerpt; Block Hooks still
apply to a subsequent real
the_contentrun.excerpt
'Visible text. LEAKED HOOKED TEXT', confirming the bug on trunk.sweep); PHPCS clean.
Trac ticket: https://core.trac.wordpress.org/ticket/66110
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code (Anthropic), Devin (Cognition)
Model(s): Claude Opus 4.8 (orchestration/review), Devin (implementation)
Used for: root-cause analysis, patch + test authorship, git fact-checking, and full test sweep; reviewed and taken responsibility for by the contributor.
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.
🤖 Generated with Claude Code