You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sage 10主题解析WordPress经典编辑器内容遇问题求助

使用Sage 10解析WordPress经典编辑器内容的问题与解决方案

问题描述

我正在使用Sage 10开发WordPress主题,在single.blade.php中解析经典编辑器(无区块)创建的内容时遇到问题。

获取文章内容的代码:

$content = get_post_field('post_content', get_the_ID());

解析函数代码:

function parse_classic_content($content) {
    $dom = new DOMDocument();
    libxml_use_internal_errors(true);
    $dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
    libxml_clear_errors();

    $body = $dom->getElementsByTagName('body')->item(0);
    $children = iterator_to_array($body->childNodes);
    $newContent = '';
    $count = 0;

    foreach ($children as $child) {
        $newContent .= $dom->saveHTML($child);
        $count++;

        if ($count % 10 === 0) {
            $newContent .= '<p>separator every 10 items</p>';
        }
    }

    return preg_replace('~<\?xml.*?~', '', $newContent);
}

遇到的问题:

  • 元素丢失:部分元素缺失或渲染不符合预期
  • 分隔符逻辑异常:分隔符未按每10个元素插入,实际间隔为5、6或7个元素

额外需求:希望在循环内检测段落元素中是否包含锚点标签(<a>)


问题分析与解决方案

1. 元素丢失问题

DOMDocument::loadHTML加载内容时会自动补全HTML结构,但body的子节点不仅包含实际内容元素(如<p>、<h2>),还会包含空白文本节点(换行、空格等),这些节点被纳入children数组后,用saveHTML输出时可能被忽略,导致元素丢失或渲染异常。另外,你写的preg_replace正则完全没必要——loadHTML不会生成XML声明,反而可能误删内容。

修复代码:

function parse_classic_content($content) {
    $dom = new DOMDocument();
    libxml_use_internal_errors(true);
    // 手动添加DOCTYPE,避免DOM自动补全多余标签
    $dom->loadHTML('<!DOCTYPE html>' . mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
    libxml_clear_errors();

    $body = $dom->getElementsByTagName('body')->item(0);
    $children = iterator_to_array($body->childNodes);
    $newContent = '';
    $count = 0;

    foreach ($children as $child) {
        // 只处理元素节点,跳过空白文本节点
        if ($child->nodeType !== XML_ELEMENT_NODE) {
            continue;
        }
        $newContent .= $dom->saveHTML($child);
        $count++;

        if ($count % 10 === 0) {
            $newContent .= '<p>separator every 10 items</p>';
        }
    }

    return $newContent;
}

2. 分隔符逻辑异常问题

根源和元素丢失一致:空白文本节点被计入了count统计,导致实际内容元素还没到10个,count已经累加了大量空白节点的数量,提前触发分隔符插入。上面的修复方案通过过滤空白节点,只统计实际HTML元素,就能保证每10个元素插入一次分隔符。

3. 检测段落中的锚点标签

在循环内先判断当前元素是否为<p>,再通过getElementsByTagName查找子节点中的<a>标签:

foreach ($children as $child) {
    if ($child->nodeType !== XML_ELEMENT_NODE) {
        continue;
    }

    // 检测段落是否包含锚点标签
    if ($child->tagName === 'p') {
        $links = $child->getElementsByTagName('a');
        if ($links->length > 0) {
            // 此处执行你需要的逻辑,比如标记该段落
            // 示例:$newContent .= '<div class="has-link">';
        }
    }

    $newContent .= $dom->saveHTML($child);
    $count++;

    if ($count % 10 === 0) {
        $newContent .= '<p>separator every 10 items</p>';
    }
}

内容的提问来源于stack exchange,提问作者user16469315

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:54:52