跳到主内容

WordPress HTML API 怎么用:用 WP_HTML_Tag_Processor 安全修改 HTML

100%
WordPress HTML API 怎么用:用 WP_HTML_Tag_Processor 安全修改 HTML

WordPress HTML API(6.2 起引入,后续持续扩展)的正确用法是:不要再用正则改 HTML 。用 WP_HTML_Tag_Processor 定位标签、读写属性、增删 class 、替换文本,最后 get_updated_html() 拿结果。它是按 HTML5 规范实现的解析器,能正确处理注释、 script/textarea 里的伪标签、单引号属性、布尔属性这些正则必踩的坑。

正则为什么一定会出错

最经典的例子是给图片加 loading="lazy"。第一版正则 ~<img(.*)>~ 会因为贪婪匹配把属性加到最后一个标签上;改成非贪婪 .*? 后,遇到 <img title="bears > tigers"> 这种属性值里带尖括号的写法就会把标记切烂;继续修,又会漏掉单引号属性、无值属性、以及已经存在 loading 属性的情况。修到第四版,正则已经没人看得懂,边界仍然不全。

更麻烦的是语义:<textarea> 里的 <img> 是纯文本不是标签,<script> 里的字符串同理。正则永远分不清这个区别,解析器可以。

同样的需求用 HTML API 一次到位:

$processor = new WP_HTML_Tag_Processor( $html );
if ( $processor->next_tag( 'img' ) ) {
    $processor->set_attribute( 'loading', 'lazy' );
}
return $processor->get_updated_html();

三步走:创建 → 查找 → 改

1. 查找标签

next_tag() 移动内部游标到下一个符合条件的标签,支持多种查询写法:

$tags = new WP_HTML_Tag_Processor( $html );

$tags->next_tag();                                     // 下一个任意标签
$tags->next_tag( 'img' );                              // 下一个 img
$tags->next_tag( array( 'class_name' => 'fullwidth' ) ); // 带指定 class 的标签
$tags->next_tag( array( 'tag_name' => 'img', 'class_name' => 'fullwidth' ) );

两条重要的行为规则:

  • 返回 false 时游标已走到文档末尾,不能回退,想重新扫描必须新建实例——唯一的例外是书签。
  • 查询语法不够用时,可以用 get_tag() / get_attribute() 在循环里自行过滤,做自定义查询。

2. 读写属性

set_attribute() 会自动完成所有 HTML 编码,你传未转义的原始值即可:传 'Eggs & Milk' 浏览器看到的就是 Eggs & Milk,不会二次转义成 &amp;。

// 布尔属性:true 只加属性名,false 移除该属性
$processor->set_attribute( 'selected', true );
$processor->set_attribute( 'selected', false );

// class 有专用方法,别直接 set_attribute( 'class', ... )
$processor->add_class( 'is-active' );
$processor->remove_class( 'old-class' );

get_attribute() 的返回值要分清三种情况:属性不存在返回 null,布尔属性返回 true,属性存在但值为空返回空字符串 ''。判断时别只用 empty(),否则会把布尔属性和空值混为一谈。

如果同一个属性被别处先写了一次,后写的值会覆盖前者,不会出现重复属性导致浏览器忽略你想要的那个。这点是相对正则追加写法的隐形优势。

3. 取回结果

所有修改都是先入队(lexical updates),最后统一由 get_updated_html() 输出。中间不产生字符串拷贝,性能也更好。

书签:唯一能「回头」的机制

默认不能回退,但可以先 set_bookmark() 再 seek() 跳回来。典型场景是「改完子元素后给父容器加属性」:

$processor = new WP_HTML_Tag_Processor( $block_content );
if ( ! $processor->next_tag() ) {
    return $block_content;
}
$processor->set_bookmark( 'parent' );

while ( $processor->next_tag( array( 'tag_name' => 'span', 'class_name' => 'word-switcher' ) ) ) {
    $processor->set_attribute( 'data-wp-text', 'state.currentWord' );
}

$processor->seek( 'parent' );
$processor->set_attribute( 'data-wp-interactive', 'my-plugin/word-switcher' );
$processor->set_attribute( 'data-wp-context', wp_json_encode( array( 'index' => 0 ) ) );

return $processor->get_updated_html();

这也是 HTML API 与 Interactivity API 配合的标准姿势:用解析器给已有标记注入 data-wp-* 指令,无需手写正则替换。

改文本内容:set_modifiable_text()

除了属性,还能改节点的文本内容。next_token() 配合 get_modifiable_text() / set_modifiable_text() 可以遍历文本节点:

while ( $processor->next_token() ) {
    if ( '#text' !== $processor->get_token_name() ) {
        continue;
    }
    $chunk = $processor->get_modifiable_text();
    if ( ! str_contains( $chunk, ':)' ) ) {
        continue;
    }
    $processor->set_modifiable_text( str_replace( ':)', '🙂', $chunk ) );
}

它同样负责编码,并且对 SCRIPT 、 STYLE 、 TEXTAREA 这类特殊元素有保护逻辑:不允许写入会提前闭合标签的内容,防止结构被破坏。写失败时返回 false,务必接住返回值。

能力边界:Tag Processor 改不了什么

WP_HTML_Tag_Processor 处理的是「标签与属性」这一层:它不理解 DOM 树结构,不能插入新标签、不能删除标签、不能包裹元素。需要改结构请用更高层的 WP_HTML_Processor,它维护完整的树信息,支持在特定深度插入/删除节点。

选择建议:只改属性、 class 、文本 → Tag Processor,够用且更快;要动结构 → HTML Processor 。

典型落地场景

  • 批量加性能优化属性:给图片加 loading="lazy"、给外链加 rel="noopener"、给 iframe 加懒加载。
  • 在 render_block 过滤器里改输出:这是最推荐的接入点,比过滤 the_content 精准得多,也不会误伤短代码输出。
  • 给核心区块注入交互指令:配合 Interactivity API,为已有区块加上前端行为而不复制其渲染逻辑。
  • 内容迁移与清洗:批量规范化旧文章的标记属性。

相关阅读


HTML API 从哪个版本可用?
HTML Tag Processor 自 WordPress 6.2 引入,后续版本持续扩展能力(如 set_modifiable_text 、书签等)。使用较新的方法前建议确认你站点核心版本已包含该特性,低版本调用不存在的方法会直接报致命错误。

next_tag() 返回 false 之后还能继续用吗?
不能。返回 false 意味着游标已到文档末尾且无法逆向移动。要重新扫描就新建一个 processor 实例;需要回到先前位置则必须提前 set_bookmark() 再用 seek() 跳回。

set_attribute 需要自己 esc_attr 吗?
不需要,也不应该。 HTML API 会按规范完成编码,你传未转义的原始值。如果先自己 esc_attr 一遍,页面上会出现 &amp; 这类二次转义的脏数据。

能用它插入或删除标签吗?
Tag Processor 不行,它只处理标签与属性层面。需要插入、删除、包裹节点请使用 WP_HTML_Processor,它维护完整树结构,能在指定位置做结构性修改。

延伸阅读:WordPress 钩子机制详解
这篇有帮助吗?
云上的幻象
云上的幻象查看主页

七彩云博客,分享 WordPress 建站实战与 AI 工具测评,覆盖服务器运维、站长工具、软件资源与电商运营干货,专注原创实用的主题插件、网站加速与安全优化教程。

847文章4评论

相关文章

评论 (0)

欢迎你,新朋友,感谢参与互动!文明发言,理性交流 · 首次评论将在审核后展示