v0.6.0 — content-replace + blocks-patch footgun guard
New: gds/content-replace
Literal find-and-replace across all blocks of a post (or many posts) in one safe, counted pass — the right tool when changing a word/phrase that appears in more than one place, instead of hand-patching each block via gds/blocks-patch.
whole_word(Unicode-aware) +case_sensitivetoggles —ilmanwon't match insideilmanvaihtoorVilman.- Tag-safe: only rewrites visible text nodes, never tag internals (
href/src/class).include_attrsopts into attribute values for blocks that store text there. dry_run: match count + context samples without writing.expect_count: aborts without writing when the real count differs — "replace 4" can't silently become 14.ids[]: same replacement across many posts in one call (plan-then-apply, combined count, singlebulkundo) for site-wide sweeps (e.g. an old email address). Pair withgds/content-list.- Fully reversible.
Fixes
blocks-patchfootgun guard:occurrence: 0combined withinner_html/inner_blocksis now rejected (it would broadcast identical content to every matching block — the page-nuking case).occurrence: 0+ attrs stays allowed.wp_slash()beforewp_update_post()in bothcontent-replaceandblocks-patch— block content with backslashes (code blocks, Windows paths, escapes) was silently corrupted on save.
Internal
- Extracted the template-aware post-id resolver into a shared
ResolvesPostIdtrait.
Full suite green (392 tests), Pint + PHPStan level 6 clean. See #28.