在 WordPress 中使用 Markdown 撰写 Mermaid 图表(如流程图、时序图)时,常遇到的两个痛点:
- 渲染冲突:代码高亮插件(如 HCB)会优先处理代码块,导致 Mermaid 无法识别被破坏的 HTML 结构。
- 性能损耗:很多 Mermaid 插件会在所有页面加载庞大的 JS 库,拖慢网站速度。
本文提供一个无需插件、纯代码的终极解决方案。核心思路是:后端 PHP 拦截清洗 + 前端 JS 按需加载。
核心原理
- PHP 端(清洗与保护):在 WordPress 输出文章内容前,使用正则拦截
language-mermaid代码块。将pre/code标签替换为 Mermaid 官方要求的div,并在服务器端清洗掉 WordPress 自动生成的<br>和 HTML 实体,彻底避免前端解析错误。 - JS 端(按需渲染):检测页面是否存在
.mermaid容器。只有存在时,才动态从 CDN 下载 Mermaid 库并渲染。无图页面 0 流量消耗。
第一步:添加后端拦截器 (PHP)
将以下代码添加到主题的 functions.php 文件末尾。这段代码负责在代码高亮插件介入前,把 Mermaid 代码“偷”出来并洗干净。
/**
* Mermaid 核心拦截器 V2.0 (增强清洗版)
* 作用:拦截 Markdown 生成的 Mermaid 代码块,清洗 HTML 标签,转换为标准 DIV
*/
function raw_mermaid_filter($content) {
// 匹配 Markdown 插件生成的 language-mermaid 代码块
$pattern = '/<pre><code class="[^"]*language-mermaid[^"]*">([\s\S]*?)<\/code><\/pre>/i';
return preg_replace_callback($pattern, function($matches) {
$code = $matches[1];
// 1. 【关键修复】将 HTML 换行标签替换为真实的换行符 \n
// 这一步解决了多行代码挤在一行导致渲染失败的问题
$code = str_replace(
array('<br>', '<br/>', '<br />', '</p>', '</div>', '</li>'),
"\n",
$code
);
// 2. 解码 HTML 实体 (如将 > 还原为 >)
$code = html_entity_decode($code, ENT_QUOTES, 'UTF-8');
// 3. 剥离所有剩余 HTML 标签,确保代码纯净
$code = strip_tags($code);
// 4. 输出标准容器
return '<div class="mermaid">' . trim($code) . '</div>';
}, $content);
}
// 挂载钩子:优先级设为 12,确保在 Markdown 解析后、但在高亮插件运行前执行
add_filter('the_content', 'raw_mermaid_filter', 12);
第二步:添加前端渲染器 (JS)
将以下代码添加到网站的 页脚 (Footer) 中(可以使用 WPCode 插件或主题设置)。
<!-- Mermaid 按需加载器 (配合 PHP 拦截器使用) -->
<script type="module">
document.addEventListener('DOMContentLoaded', async () => {
// 1. 检查页面上有没有 PHP 生成好的 mermaid div
const graphs = document.querySelectorAll('.mermaid');
// 2. 如果没找到,直接结束,不下载任何库 -> 0 流量消耗,0 性能损耗
if (graphs.length === 0) {
return;
}
// 3. 只有存在图表时,才动态下载 Mermaid 库
const { default: mermaid } = await import('https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs');
// 4. 初始化并渲染
// 因为 PHP 已经把脏标签都洗干净了,这里直接 run 就行,非常快
mermaid.initialize({ startOnLoad: false, theme: 'default' });
await mermaid.run({
querySelector: '.mermaid'
});
});
</script>
方案优势
- 极致性能:没有图表的文章页面,JS 执行时间微乎其微,且不会加载额外的 JS 文件。
- 兼容原生 Markdown:直接使用 mermaid 语法写作,无需短代码。
- 彻底解决冲突:通过 PHP 转换标签,代码高亮插件根本“看”不到 Mermaid 代码,完美规避了语法高亮带来的结构破坏。
- 自动更新:直接调用 jsDelivr CDN 的最新版 Mermaid,无需维护插件。
留言
1. 添加到主题的 functions.php 文件末尾 2. 添加到网站的 页脚 (Footer) 中