wp-html-api

Use WordPress' HTML API for safe server-side HTML inspection and mutation instead of regex, fragile string replacement, or DOMDocument. Covers WP_HTML_Tag_Processor, WP_HTML_Processor, set_attribute, remove_attribute, add_class, remove_class, set_modifiable_text, serialize_token, custom data attribute name mapping, and WP 6.9 behavior where attribute/text setters escape character references. Use when plugin code modifies rendered HTML, block output, shortcodes, content filters, widget markup, email fragments, or user-provided HTML.

Best use case

wp-html-api is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use WordPress' HTML API for safe server-side HTML inspection and mutation instead of regex, fragile string replacement, or DOMDocument. Covers WP_HTML_Tag_Processor, WP_HTML_Processor, set_attribute, remove_attribute, add_class, remove_class, set_modifiable_text, serialize_token, custom data attribute name mapping, and WP 6.9 behavior where attribute/text setters escape character references. Use when plugin code modifies rendered HTML, block output, shortcodes, content filters, widget markup, email fragments, or user-provided HTML.

Teams using wp-html-api should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/wp-html-api/SKILL.md --create-dirs "https://raw.githubusercontent.com/nvdigitalsolutions/mcp-ai-wpoos/main/.agents/skills/wp-html-api/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/wp-html-api/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How wp-html-api Compares

Feature / Agentwp-html-apiStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use WordPress' HTML API for safe server-side HTML inspection and mutation instead of regex, fragile string replacement, or DOMDocument. Covers WP_HTML_Tag_Processor, WP_HTML_Processor, set_attribute, remove_attribute, add_class, remove_class, set_modifiable_text, serialize_token, custom data attribute name mapping, and WP 6.9 behavior where attribute/text setters escape character references. Use when plugin code modifies rendered HTML, block output, shortcodes, content filters, widget markup, email fragments, or user-provided HTML.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# WordPress HTML API

Use this skill when plugin code needs to read or modify HTML. The goal is to avoid regex-based HTML parsing and unsafe manual escaping. WordPress' HTML API understands malformed real-world HTML better than ad hoc string code and keeps escaping rules in one place.

This skill is not about React, Gutenberg editor internals, or client-side DOM work.

## When to use this skill

Trigger when ANY of the following is true:

- Code uses regex or `str_replace()` to modify HTML tags, attributes, classes, or text nodes.
- Code uses `DOMDocument` for frontend HTML fragments and then fights encoding, wrapper tags, or HTML5 parsing differences.
- The task mentions `WP_HTML_Tag_Processor`, `WP_HTML_Processor`, `set_attribute`, `add_class`, `serialize_token`, or `data-*` attributes.
- A plugin filters `the_content`, shortcode output, widget output, email HTML, REST-rendered HTML, or third-party markup.

## Pick the right processor

| Task | Prefer |
|---|---|
| Add/remove/read attributes on matching tags | `WP_HTML_Tag_Processor` |
| Add/remove classes on matching tags | `WP_HTML_Tag_Processor` |
| Replace text in modifiable text nodes | `WP_HTML_Tag_Processor::set_modifiable_text()` |
| Traverse nested structure or serialize matched tokens | `WP_HTML_Processor` |
| Normalize malformed HTML into well-formed HTML | `WP_HTML_Processor::normalize()` |
| Map between `data-*` HTML names and JS `dataset` names | `wp_js_dataset_name()` / `wp_html_custom_data_attribute_name()` |

For most plugin output filters, start with `WP_HTML_Tag_Processor`. Reach for `WP_HTML_Processor` only when you need document/fragment structure, nesting, or token serialization.

## Attribute and class mutation

```php
function myplugin_add_tracking_attr( string $html ): string {
    $processor = new WP_HTML_Tag_Processor( $html );

    while ( $processor->next_tag( array( 'tag_name' => 'a' ) ) ) {
        $href = $processor->get_attribute( 'href' );
        if ( ! is_string( $href ) || ! str_starts_with( $href, 'https://example.com/' ) ) {
            continue;
        }

        $processor->add_class( 'myplugin-tracked-link' );
        $processor->set_attribute( 'data-myplugin-source', 'content' );
    }

    return $processor->get_updated_html();
}
```

Important WP 6.9 behavior: `set_attribute()` and `set_modifiable_text()` escape all character references. Pass normal unescaped text. Do not pre-escape with `esc_attr()`, `esc_html()`, or `htmlspecialchars()` before calling these methods, or you will produce double-escaped output.

```php
// WRONG - pre-escaped value can become double-escaped.
$processor->set_attribute( 'title', esc_attr( 'Eggs & Milk' ) );

// RIGHT - pass the raw intended value; HTML API encodes it.
$processor->set_attribute( 'title', 'Eggs & Milk' );
```

## Text node mutation

`set_modifiable_text()` only works when the current token is modifiable text. It is not a general "replace all visible text" function.

```php
$processor = new WP_HTML_Tag_Processor( $html );

while ( $processor->next_token() ) {
    if ( '#text' !== $processor->get_token_type() ) {
        continue;
    }

    $text = $processor->get_modifiable_text();
    if ( null === $text ) {
        continue;
    }

    $processor->set_modifiable_text( str_replace( ':)', '🙂', $text ) );
}

$html = $processor->get_updated_html();
```

If the target text may be inside `script`, `style`, or complex nested content, inspect the processor behavior on the target WP version before shipping.

## Structural extraction

Use `WP_HTML_Processor` when you need safe token serialization or fragment-level structure:

```php
$processor = WP_HTML_Processor::create_fragment( $html );
$links     = array();

while ( $processor->next_tag( array( 'tag_name' => 'a' ) ) ) {
    $links[] = $processor->serialize_token();
}
```

In WP 6.9, `WP_HTML_Processor::serialize_token()` is public. It serializes the current token in normalized form; it is not a full `outerHTML` extractor for arbitrary subtrees unless you explicitly walk and collect the nested tokens you need.

## `data-*` attribute names

HTML `data-*` names and JS `dataset` properties do not map by simple dash removal in every case. For generated attributes that must line up with JS, use the core mapping helpers:

```php
$attribute = wp_html_custom_data_attribute_name( 'myPluginSource' );
if ( null !== $attribute ) {
    $processor->set_attribute( $attribute, 'content' );
}

$dataset_name = wp_js_dataset_name( 'data-my-plugin-source' );
```

## Critical rules

- **Do not parse HTML with regex** when the task is tag, attribute, class, or text-node aware.
- **Do not pre-escape values passed to HTML API setters.** Pass the intended raw string; the API encodes it.
- **Use `WP_HTML_Tag_Processor` first** for simple mutations; it is cheaper and simpler than structural processing.
- **Use `WP_HTML_Processor` for structure**, nested traversal, normalization, and `serialize_token()`.
- **Return `get_updated_html()`** after lexical updates; returning the original `$html` drops changes.
- **Test malformed HTML.** Plugin output often receives fragments, not clean full documents.

## Common mistakes

```php
// WRONG - regex breaks on attribute order, quotes, nesting, and malformed HTML.
$html = preg_replace( '/<a /', '<a rel="nofollow" ', $html );

// RIGHT
$p = new WP_HTML_Tag_Processor( $html );
while ( $p->next_tag( array( 'tag_name' => 'a' ) ) ) {
    $p->set_attribute( 'rel', 'nofollow' );
}
$html = $p->get_updated_html();

// WRONG - escapes before the API escapes.
$p->set_attribute( 'title', esc_attr( $title ) );

// RIGHT
$p->set_attribute( 'title', $title );
```

## Cross-references

- Run **`wp-security-audit`** when HTML contains user input or saved admin settings.
- Run **`wp-i18n-audit`** when replacing visible text with translated strings.
- Run **`wp-rest-api`** when HTML is returned from an endpoint and should instead be structured JSON.

## What this skill does NOT cover

- Client-side DOM manipulation.
- Gutenberg editor component development.
- KSES policy design beyond choosing safe output mutation primitives.

## References

- WordPress 6.9 HTML API dev note: <https://make.wordpress.org/core/2025/11/21/updates-to-the-html-api-in-6-9/>
- `WP_HTML_Tag_Processor`: [wp-includes/html-api/class-wp-html-tag-processor.php](wp-includes/html-api/class-wp-html-tag-processor.php)
- `WP_HTML_Processor`: [wp-includes/html-api/class-wp-html-processor.php](wp-includes/html-api/class-wp-html-processor.php)
- Dataset helpers: [wp-includes/script-loader.php](wp-includes/script-loader.php)

Related Skills

webapp-testing

5
from nvdigitalsolutions/mcp-ai-wpoos

Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.

web-artifacts-builder

5
from nvdigitalsolutions/mcp-ai-wpoos

Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.

valyu

5
from nvdigitalsolutions/mcp-ai-wpoos

Search the live web and 36+ specialised data sources including SEC filings, PubMed, ChEMBL, clinical trials, FRED economic indicators, and patent databases. Use when current, authoritative, or paywalled data is required.

ui-ux-pro-max

5
from nvdigitalsolutions/mcp-ai-wpoos

AI-powered design intelligence with 67 UI styles, 161 color palettes, 57 font pairings, 99 UX guidelines, and 25 chart types across 15+ tech stacks. Generates complete design systems for any product type with industry-specific reasoning rules.

theme-factory

5
from nvdigitalsolutions/mcp-ai-wpoos

Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.

slack-gif-creator

5
from nvdigitalsolutions/mcp-ai-wpoos

Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a GIF of X doing Y for Slack."

skill-creator

5
from nvdigitalsolutions/mcp-ai-wpoos

Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.

shannon

5
from nvdigitalsolutions/mcp-ai-wpoos

Autonomous AI security pen testing. Executes real exploits against web applications to find SQL injection, XSS, SSRF, authentication flaws, and IDOR vulnerabilities. Reports only confirmed, reproducible findings — no false positives.

remotion

5
from nvdigitalsolutions/mcp-ai-wpoos

Create programmatic videos using React and Remotion. Translate natural language descriptions into working Remotion components for product demos, release announcements, explainer videos, and animated content.

planetscale

5
from nvdigitalsolutions/mcp-ai-wpoos

Design schemas and write queries for PlanetScale serverless MySQL using branch-based workflows. Ensures index coverage, avoids foreign key anti-patterns, and treats every schema change as a reviewable, reversible deploy request.

mcp-builder

5
from nvdigitalsolutions/mcp-ai-wpoos

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

karpathy-coding-principles

5
from nvdigitalsolutions/mcp-ai-wpoos

Apply Karpathy-inspired coding behavior guidelines — think before coding, prefer simplicity, make surgical changes, and execute toward verifiable goals. Reduces wrong assumptions, overengineering, and unintended side-effects.