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
相关产品推荐
相关产品推荐

