Obsidian 插件:Hexo Publisher

在 Obsidian 里用样式预设新建 Hexo 文章,写完点一下侧边栏图标就发布到 GitHub Pages。这是给我自己博客写的工具,最近整理成了开源项目,本文既是使用说明,也是它的开源文档。

它到底解决什么问题

写 Hexo 文章的麻烦从来不在正文,而在 front matter:每篇都要写 title、date、cover、mathjax、top_img、type、tags、categories,还得注意字段顺序、列表缩进、分类层级。错一个地方,生成出来就是个坏页面;而列表用 tab 缩进更隐蔽——Hexo 自己勉强能读,但 Obsidian 的属性面板、GitHub 预览、prettier 全都会报错,因为它们按严格的 YAML 解析。

这个插件把这件事压缩成两次点击:

命令 侧边栏图标 作用
Hexo: 新建文章(选择样式预设) 新建文件 选预设、填标题,自动在 _posts/ 建好文章,front matter 按固定规范写好
Hexo: 校验文章 front matter 无 调用你站点里的检查脚本,把不合规的文章拦在发布之前
Hexo: 发布到 GitHub Pages 上传 调用你站点里的发布脚本,成功只出一条通知,失败才弹日志

和已有插件的区别

Obsidian 官方插件市场目前有 8424 个插件,其中和 Hexo 相关的只有两个:

插件 作者 它的定位
Hexo Toolkit sissilab 维护 Hexo 文章
Hexo Send BeckChan 准备笔记、生成提交、确认后推送(未经 Obsidian 人工审核)

Hexo Publisher 的定位是发布流水线的最小前端:它不自己实现 git 操作,也不假设你用哪种部署方式,而是直接调用你站点里已经调试好的 npm 脚本。好处是部署方式随你改(hexo-deployer-git、GitHub Actions、rsync 都行),插件不用跟着改;代价是它需要你的站点能跑 npm。

安装

  1. 下载或 clone 仓库。
  2. 把整个文件夹放进 <你的仓库>/.obsidian/plugins/hexo-publisher/,里面必须同时有 main.js、manifest.json、styles.css 三个文件。
  3. Obsidian 打开 设置 → 第三方插件,关闭”受限模式”,然后启用 Hexo Publisher。

仓库地址:https://github.com/ohepse/obsidian-hexo-publisher

推荐的仓库布局

直接把 Hexo 的 source/ 目录当作 Obsidian 仓库,这样路径天然对齐:文章在 _posts/xxx.md,图片在 img/posts/。再配合两个设置:

  • 设置 → 文件与链接 → 新链接格式:绝对路径
  • 设置 → 文件与链接 → 使用 [[Wikilinks]]:关闭

这样粘贴一张图片,Obsidian 写出来的就是 ![](/img/posts/xxx.png),正好是 Hexo 需要的路径,不用再手改。另外 Hexo 会跳过以点开头的目录,所以 .obsidian/ 不会被发布到站点里。

配置

站点路径和样式预设都写在插件目录下的 data.json 里(这个文件属于你的运行时数据,不在仓库内;文件不存在时会用内置的默认预设):

1
2
3
4
5
6
7
8
9
10
{
"siteRoot": "D:\\path\\to\\your-hexo-site",
"siteUrl": "https://example.com",
"presets": {
"普通文章": { "mathjax": false, "tags": [], "categories": [] },
"带公式的长文": { "mathjax": true, "tags": [], "categories": [] },
"加密文章": { "mathjax": false, "password": "changeme", "tags": [], "categories": [] },
"置顶": { "mathjax": false, "sticky": 1, "tags": [], "categories": [] }
}
}

预设里的每个字段都会原样写进新文章的 front matter。常用字段:

字段 作用
mathjax 是否为该文章加载公式渲染
cover 列表页封面图,如 /img/posts/xxx.png
top_img 文章顶部图,transparent 表示不显示
password 文章加密密码(需配合加密类插件)
sticky 置顶
toc、comments、copyright 单篇的目录、评论、版权开关

字段顺序是固定的:title、date、cover、description、mathjax、password、updated、top_img、sticky、hide、comments、abbrlink、type,然后是 tags、categories,最后是其它自定义字段;列表一律 2 空格缩进。改完 data.json 后,在设置里把插件关掉再打开即可生效。

发布是怎么工作的

插件在 siteRoot 下执行 npm run publish,发布做什么由你决定。我自己的配置是这样,先校验再发布:

1
2
3
4
"scripts": {
"check": "node tools/frontmatter-check.mjs --check",
"publish": "npm run check && hexo clean && hexo generate && hexo deploy"
}

这里有个容易踩的坑:单独跑 hexo deploy 不会重新生成 public/,它会把上一次的旧产物原样推上线。所以一定要把 clean → generate → deploy 串起来。

发布过程中进度显示在右下角状态栏;成功只弹一条通知,失败才会自动弹出日志窗口显示完整输出,这样既不打扰日常使用,出错时又能直接看到原因。

几个实现上的取舍

为什么是单文件插件。 Obsidian 的插件加载器是把 main.js 交给 window.eval 执行的,只提供一个白名单 require。我最初按常规 Node 习惯把纯逻辑拆成 lib.js 再 require('./lib.js'),结果插件直接”无法开启”——加载阶段抛错,UI 只给一句模糊提示。所以这个插件的所有代码都内联在一个文件里,这也意味着它不需要任何构建步骤,clone 下来就能用。

为什么强调 tab 缩进。 front matter 里的 tab 是非法 YAML。写这个插件之前,我博客里 39 篇文章有 37 篇是 tab 缩进的,只是因为 Hexo 的解析器足够宽容才一直没暴露。一旦要交给编辑器或其它工具读写,这就是颗定时炸弹,所以我先统一成了 2 空格。

为什么要有前端闸门。 校验脚本跑在发布之前,格式不对就直接中断,而不是生成一个坏页面再等你发现。这条对自动化发布尤其重要——没人会去逐页检查。

已知限制

  • 仅桌面端:它需要启动本地进程,移动端用不了(manifest 里已标 isDesktopOnly)。
  • 依赖 PATH 里的 npm,以及站点目录下已安装的 node_modules/。
  • 一次只跑一个任务,发布过程中再点会被拒绝。
  • Windows 上命令走 cmd.exe /c npm.cmd ...(带 windowsHide,不会闪出命令行窗口);macOS 和 Linux 按同样的 npm 脚本约定工作。

开源信息

  • 许可:MIT,随便用、随便改。
  • 仓库:https://github.com/ohepse/obsidian-hexo-publisher
  • 问题和建议欢迎提 issue;如果你的站点有更特别的发布流程,也欢迎说说,这个插件本来就是围着”发布脚本”这个接口设计的。