为什么需要这套工作流

用 WordPress 后台写文章,体验一言难尽——富文本编辑器臃肿,Gutenberg 块编辑器对 Markdown 重度用户不友好,代码块和数学公式的支持更是灾难。

我日常用 Obsidian 做笔记和写作,Markdown 原生、本地优先、双链好用。所以核心诉求很简单:在 Obsidian 里写完,几步操作就能发到 WordPress 上,保留 Markdown 原始格式,不做任何手动复制粘贴。

最终方案跑了一段时间,稳定可用,这篇文章把整套架构分享出来。

整体架构

Obsidian Vault (本地 Markdown 文件)
│
▼
Vault Sync Server (轻量 HTTP API,暴露文件列表和内容)
│
▼
QNTLab Vault 插件 (WP Admin 中浏览、预览、一键导入)
│
▼
WordPress 数据库 (post_content 存原始 Markdown)
│
▼
Parsedown 实时渲染 (前端访问时 Markdown → HTML)
│
▼
Kimi AI 自动摘要 (可选,调用月之暗面 API 生成中文摘要)

下面逐层拆解。

第一层:Obsidian 写作规范

在 Obsidian 里写文章时,我遵循一个简单的 YAML frontmatter 约定:

---
title: 文章标题
tags: [标签1, 标签2, 标签3]
summary: 一句话摘要(可选,不写的话后面 AI 会自动生成)
---

正文内容,正常写 Markdown 就行...

这三个字段会在导入 WordPress 时被自动解析:

  • title → 文章标题
  • tags → WordPress 标签
  • summary → 文章摘要 / excerpt

正文部分随意使用 Markdown 语法——标题、列表、代码块、加粗、行内代码,全部支持。数学公式用 $...$(行内)和 $$...$$(块级),前端通过 KaTeX 渲染。

第二层:Vault Sync Server

Obsidian 的文件在本地,WordPress 在服务器上,中间需要一个桥梁。我用一个轻量的 HTTP 服务把 Vault 目录暴露为 API:

  • GET /api/files — 返回所有 .md 文件的路径和大小
  • GET /api/file?path=xxx.md — 返回指定文件的原始内容
  • Bearer Token 认证,防止未授权访问

这个服务可以用任何语言写,几十行代码的事。也可以用现成的 Obsidian Local REST API 插件,或者干脆用 Python 的 http.server 加个路由。

关键是让 WordPress 能通过 HTTP 拿到 Vault 里的文件。

第三层:QNTLab Vault 插件

这是整套工作流的核心——一个自己写的 WordPress 插件,代码不到 250 行。

功能

在 WP Admin 侧边栏会多出一个 “Vault” 菜单,包含两个页面:

文件浏览页:列出 Vault 中所有 Markdown 文件,支持搜索,显示导入状态(已导入 / 未导入)。

预览页:点击任意文件可以预览渲染效果,自动解析 frontmatter 填充标题、标签、摘要字段,然后一键 “Import as Draft” 或 “Update Post”。

核心逻辑

插件通过 wp_remote_get 调用 Sync Server 的 API:

private function api_get($endpoint, $params = []) {
$s = $this->get_settings();
$url = rtrim($s['api_url'], '/') . $endpoint;
if ($params) $url .= '?' . http_build_query($params);
$resp = wp_remote_get($url, [
'headers' => ['Authorization' => 'Bearer ' . $s['api_token']],
'timeout' => 30,
]);
if (is_wp_error($resp)) return $resp;
return wp_remote_retrieve_body($resp);
}

导入时,解析 frontmatter,把纯 Markdown 正文存入 post_content,同时在 _vault_path 这个 post meta 里记录来源路径,用于后续更新时匹配:

$post_id = wp_insert_post([
'post_title' => $title,
'post_content' => $parsed['body'], // 原始 Markdown
'post_status' => 'draft',
'post_excerpt' => $summary,
]);
update_post_meta($post_id, '_vault_path', $vault_path);

导入后默认是草稿状态,在 WP 后台确认无误后手动发布。如果 Obsidian 里修改了同一篇文章,回到 Vault 页面点 “Update Post” 即可同步更新。

第四层:Markdown 实时渲染

WordPress 数据库里存的是原始 Markdown,不是 HTML。渲染发生在前端访问时,通过 Parsedown 库实现:

require_once get_template_directory() . '/lib/Parsedown.php';

function qntlab_render_markdown($content) {
if (strpos($content, '```') !== false || strpos($content, '##') !== false
|| strpos($content, '**') !== false || strpos($content, '- ') !== false) {
remove_filter('the_content', 'wpautop');
$parsedown = new Parsedown();
$parsedown->setSafeMode(false);
return $parsedown->text($content);
}
return $content;
}
add_filter('the_content', 'qntlab_render_markdown', 5);

几个关键设计决策:

  1. 禁用 Gutenbergadd_filter('use_block_editor_for_post', '__return_false'),用经典编辑器,避免块编辑器破坏 Markdown 格式
  2. 禁用 wpautop:WordPress 默认会把换行转成 `

`,这会和 Parsedown 的输出冲突,所以在渲染前移除 3. 渲染优先级为 5:在 heading ID 注入(优先级 10)和 TOC 生成(优先级 20)之前执行,确保后续处理拿到的是 HTML

自动目录生成

渲染后的 HTML 会经过两道 filter:

  • 优先级 10:给所有 `

    ` ~ `

    ` 自动加上 `id` 属性(基于标题文本生成 slug)

  • 优先级 20:扫描所有带 id 的标题,生成侧边栏目录(TOC) 这样每篇文章自动有可跳转的目录,不需要手动维护。

数学公式

前端加载 KaTeX,自动渲染 $...$$$...$$

renderMathInElement(document.body, {
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false}
],
throwOnError: false
});

在 Obsidian 里写的公式,发布后直接能渲染,零额外操作。

第五层:AI 自动摘要(可选)

接入了月之暗面(Kimi)的 API,自动为文章生成中文摘要。

工作方式

  1. 取文章纯文本(去 HTML 标签),截取前 3000 字
  2. 发给 Kimi API,prompt 是 “请为以下文章生成一段简洁的中文摘要,不超过100字”
  3. 返回结果存入 _ai_summary post meta

三种触发方式

  • 编辑器侧边栏:每篇文章的编辑页面有个 “AI Summary” meta box,点按钮即时生成
  • 后台批量生成:Settings → AI Summary 页面,一键为所有没有摘要的文章批量生成
  • CLI 脚本php wp-content/themes/qntlab/cli-gen-summaries.php,适合 SSH 到服务器上跑

摘要会显示在首页文章列表中,带一个小标记表示是 AI 生成的。

日常使用流程

实际操作起来很简单:

  1. 在 Obsidian 里写文章,加好 frontmatter
  2. 确保 Sync Server 在运行
  3. 打开 WP Admin → Vault,找到文章,点 Preview
  4. 确认标题、标签、摘要,点 “Import as Draft”
  5. 在文章编辑页检查一下,点发布
  6. (可选)点 “Generate AI Summary” 生成摘要

修改文章时,在 Obsidian 里改完,回到 Vault 页面点 “Update Post” 即可。

这套方案的优缺点

优点:

  • 写作体验好,Obsidian 的 Markdown 编辑器比任何 WP 编辑器都强
  • 本地优先,离线也能写,不依赖网络
  • 原始 Markdown 存储,数据可迁移,不被 WordPress 绑定
  • 代码量极少,插件不到 250 行,好维护
  • 数学公式、代码高亮开箱即用

缺点 / 局限:

  • 需要维护一个 Sync Server(虽然很轻量)
  • 图片需要单独处理(目前手动上传到 WP 媒体库,或用图床)
  • 不是全自动——需要手动点导入和发布(但这也算个优点,多了一道人工审核)
  • Obsidian 的双链 [[]] 语法不会被转换,发布前需要避免或手动处理

技术栈总结

组件 技术
写作工具 Obsidian
文件同步 自建 HTTP API(Vault Sync Server)
CMS WordPress(禁用 Gutenberg)
导入插件 QNTLab Vault(自研,~250 行 PHP)
Markdown 渲染 Parsedown(PHP,实时渲染)
数学公式 KaTeX(前端 JS)
AI 摘要 月之暗面 Kimi API
目录生成 自动,基于 heading ID

写在最后

这套工作流的核心理念是:写作归写作,发布归发布,各司其职。 Obsidian 负责提供最好的写作体验,WordPress 负责展示和分发,中间用最少的代码把它们连起来。

如果你也是 Obsidian 用户,又在用 WordPress 做博客,希望这篇文章能给你一些启发。整套方案的代码量很小,完全可以根据自己的需求调整。