Repository navigation
fix(tools): decode entities in post, page and media titles - #269
Conversation
wp_create_post, wp_delete_post and wp_get_post_revisions printed title.rendered as WordPress returns it, so "Q&A" came back as "Q&A"; list/get/update had been fixed in #263. The page and media tools had the same raw-title lines, and wp_get_media printed the caption HTML. displayTitle() moves to src/utils/htmlText.ts and every one of these now goes through it (captions through htmlToPlainText()). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Reviewer's GuideCentralizes WordPress rendered-title normalization and applies it across post, page, and media outputs, while converting media captions to plain text and adding comprehensive regression coverage for entity decoding, markup stripping, and empty-title handling. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
🟡 Changes recommended
The new test placement violates the repository test-layout contract, and the documentation overstates the implemented formatting guarantee.
2 open findings
What changed in this PR
Centralizes plain-text title formatting and applies it across post, page, and media tool responses.
Changes:
- Exports and reuses
displayTitle(). - Decodes titles and media captions in affected handlers.
- Adds regression tests and rendered-field guidance.
| File | Description |
|---|---|
src/utils/htmlText.ts |
Exports shared title formatting. |
src/tools/posts/PostHandlers.ts |
Formats create, delete, and revision titles. |
src/tools/pages.ts |
Formats page titles. |
src/tools/media.ts |
Formats media titles and captions. |
src/tools/AGENTS.md |
Documents rendered-field handling. |
tests/tools/posts/PostOutputFormatting.test.js |
Tests post title formatting. |
tests/tools/titleEntityDecoding.test.js |
Tests page, media, and utility formatting. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Review follow-up: tests/AGENTS.md wants tests to mirror src/. The displayTitle cases move to tests/utils/htmlText.test.js and the page and media cases into PageTools.test.js / MediaTools.test.js; tests/tools/titleEntityDecoding.test.js is removed. The AGENTS.md rule now names the tools it covers (post, page, media) and says the SEO engines still pass title.rendered through unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up: - The >50-post streaming path labelled an empty title "Untitled" while every other path says "(untitled)"; it now uses displayTitle() too. - displayTitle() takes string | null | undefined, so passing the title object instead of .rendered no longer type-checks. - The comment in handleCreatePost claimed validatePostParams runs content through sanitizeHtml(); it uses isUnsafeWordPressContent and passes content through unchanged (sanitizeHtml corrupts Gutenberg markup). Corrected so nobody "restores" it. - Tests for an empty/markup-only page title on delete (falls back to the ID) and a media item without a caption field. - src/tools/AGENTS.md: which rendered fields carry tags; htmlText.js in the shared imports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## [4.1.2](v4.1.1...v4.1.2) (2026-10-10) ### 🐛 Bug Fixes * **tools:** decode entities in post, page and media titles ([#269](#269)) ([f8cfade](f8cfade))
|
🎉 This PR is included in version 4.1.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |

Pull Request
Description
wp_create_post,wp_delete_postandwp_get_post_revisionsprintedtitle.renderedexactly as WordPress returns it, so a title with&came back asQ&A(open P3 in the v4.0.9 re-test results). #263 fixed list/get/update for posts only. The page and media tools have the same raw-title lines, andwp_get_mediaprinted the caption's HTML (<p>…</p>).Type of Change
Changes Made
displayTitle()(markup stripped, entities decoded once,(untitled)when empty) moves fromPostHandlers.tsintosrc/utils/htmlText.tsand is exportedhtmlToPlainText()(it already falls back to the ID when there is no title)htmlToPlainText()src/tools/AGENTS.md: rendered fields are HTML and are printed through these helpers, never rawtests/tools/posts/PostOutputFormatting.test.js. Following review,displayTitlecases are intests/utils/htmlText.test.jsand the page/media cases intests/tools/pages/PageTools.test.js/tests/tools/media/MediaTools.test.js, so each test sits in the suite that mirrors its source (tests/AGENTS.md)title.renderedthrough unchanged in their structured results; that is out of scope hereTesting
format:check,security:scanNews & Articles→ "News & Articles" inwp_get_pageandwp_list_pages; site1 media 1500…1030×687.jpg→1030×687; site2 revisions show“Take the Point…”andT’ai Chi’sDocumentation
src/tools/AGENTS.md)Security
Independent review follow-up
displayTitle()like every other path ("(untitled)").displayTitle()acceptsstring | null | undefined, so passing the title object no longer type-checks.handleCreatePostthat said content goes throughsanitizeHtml(); it goes throughisUnsafeWordPressContentand is otherwise unchanged.🤖 Generated with Claude Code
Summary by Sourcery
Normalize WordPress-rendered titles and captions across post, page, and media tool output.
Bug Fixes:
Enhancements:
Documentation:
Tests: