之前一直使用印象笔记作为主力的笔记软件,但印象笔记这几年广告加的越来越离谱,遂开始寻找其替代品,几经搜索,最终确定将 Obsidian 作为自己的主力笔记软件。
Obsidian 只是一个本地笔记,如果需要多端同步,那么需要借助 Remotely Save
等插件实现。由于自己有 NAS,因此在 NAS 上部署了 WebDAV 服务,在 Remotely Save
插件中配置完毕后,实现了家、手机、公司三端的笔记同步。
除了使用 Obsidian 记录笔记外,自己还有一个对外的博客,用于发布一些内容上相对还比较完整的文章。
博客基于 Hugo 静态网站工具生成,Hugo 元数据使用 Git 管理,并托管在 Github 上,这与大部分静态博客的维护方式相同,唯一的区别在于自己的博客没有使用 Github pages,而是部署在了自己的海外服务器上,以便获得相对更好的国内访问体验。
过去,自己的发布博客的流程是,
- 创建 Hugo 文章目录和 index. Md 文件。
- 将 Obsidian 笔记中的内容拷贝到 index. Md 文件中。
- 将 obsidna 中依赖的图片(图片存储在本地)拷贝到 Hugo 文章目录下(自己大部分情况下未使用图床,图片直接放在 Hugo 文章目录下,并最终同步到自己的服务器上)。
- 修改 index. Md 文章的图片引用方式(Obsidian 基于
![[]]
,而 Hugo 则使用标准 Markdown![]()
的方式)。 - 提交 Hugo 博客文章到 Github,之后基于 WebHook 自动构建博客并同步到自己的服务器上。
如果文章内容有更改,那么则,
- 更改 Obsidian 笔记的内容。
- 复制拷贝到 Hugo 文章目录下。
- 提交 Hugo 博客内容到 Github。
整个过程相当的繁琐,尤其是涉及文章的内容更新时,很容易出现 Hugo 博客内容改了,但 Obsidian 没改,或是 Obsidian 内容改了,而 Hugo 博客忘了改的情况。
近段实在不能忍,遂打算将整个流程自动化起来,实现 Obsidian 到 Hugo 博客的自动更新同步。
网上参考了几篇文章,看到了两种方案。
- 将整个 Hugo 仓库当成一个 Obsidian 库,在 Obsidian 编辑后,同步到 Git,然后通过 Git actions 自动将文章构建发布。其中通过 draft 参数控制文章是否发布。
- 相关文章
- 优点:整个方案确实比较流畅自动化。
- 缺点:Obsidian 目录结构需要按照 Hugo 规范,不能自定义目录结果。
- 方案 2,使用 hugo-publish 等插件,将 Obsidian 文章转换后同步到 Hugo 目录里。
- 相关文章:
- 优点:笔记是笔记,博客是博客,两个目录隔离开。
- 缺点:同步到博客后,还需手动提交博客目录,才能发布。整个过程不流畅。
以上两个方案我都不是很满意,期望实现方式是将两者结合起来。
依旧分为 Obsidian 笔记库和 Hugo 博客库,在 Obsidian 里编辑笔记并无误后,添加 #blog
或是其他标志,会自动的将对笔记进行格式转换并把笔记及相关的资源拷贝到 Hugo 库目录,之后自动提交 Hugo 仓库触发静态页面构建,进而更新博客。
综合上述流程、笔记管理方式以及我的能力,我决定这样实现。
- 家、公司、手机上的 Obsidian 笔记现在通过 WebDAV 的方式同步到 NAS 上。
- 在 NAS 上创建 Hugo 博客仓库。
- 实现脚本并部署在 NAS 上,脚本循环执行以下逻辑。
- 遍历 Obsidian 库中的所有笔记,检测笔记是否有
#blog
标签。 - 如果有,那么将笔记的格式转换为 Hugo 博客形式,包括头、引用的链接、图片等。
- 将转换后的文章生成到 Hugo 目录下。
- 如果文章有引用图片,将图片拷贝到 Hugo 库的文章目录下。
- 记录笔记的 md 5 信息,用于后续比对笔记内容是否有更新。
- 提交 Hugo 仓库
- 遍历 Obsidian 库中的所有笔记,检测笔记是否有
- Hugo 仓库更新后,触发 Github 上配置的 WebHook,最终触发博客的更新。
通过以上流程,只需要在我写好的笔记中添加 #blog
标签,那么等一会,博客就会自动更新。而当我更新笔记后,这个流程也会将更新后的笔记自动更新到我的博客上。实属懒人必备。
整个流程使用 Python 实现也比较简单,我已经提交到 Github 仓库 中,可自行阅读调整。
针对脚本的功能,这里说明几点。
- 脚本执行需要
-op
、-hp
、-i
、-b
这四个参数,其中,-op
用来执行 Obsidian 库的根目录。-hp
指定 Hugo 库的根目录。-i
指定脚本每次循环执行的间隔,单位秒。-b
指定 Bark 通知的 URL 地址。
- 脚本会在当前目录下生成
obsidian2hugo_cfg.json
配置文件,存储已经生成博客的笔记的 MD 5 信息,用于检测博客内容是否有更新。 - 脚本解析 Markdown 使用了 mistletoe 库,主要用于解析获取
#blog
、![[]]
等关键字,没有使用正则替换,避免这些关键字写在代码段中。 - 脚本只处理了
#
、![[]]
关键字,对[[]]
关键字没有做任何替换处理,原因是自己没想好该怎么做。一种做法是递归将引用的文章都发表为博客,由于我目前很少使用[[]]
,因此暂时没有处理。 - 脚本使用 Bark 进行了异常通知,如果脚本执行出现异常,那么会将异常的堆栈通过 Bark 进行通知。如果需要使用 Bark,那么就指定
-b
参数,否则无需指定。如果想要其他通知方式,可自行修改代码。
在我脚本写完并开始写整理这篇文章时,我发现已经有现成的工具可以更好的实现我这个需求,而且也是我理想中的形式。
在使用 Obsidian 免费建个人博客 | PrintLove 这篇文章中,介绍了 Github Publisher 插件,这个插件可以将 Obsidian 库中的指定文章 (基于标签) 做一些替换操作后发布到 Github 的指定目录中,而且不需要 NAS、WebDAV 同步中转,对大多数人来说更为友好。
在自己造轮子前果然还是应该多找一些资料的😭。不过既然代码都写完了,还是整理下自己的方案,给大家一些参考。