Obsidian 一键发布博客与首页热力图设计文档

1. 目标

为现有 Hexo 个人博客增加一套可长期使用的发文流程:

  1. 用户在电脑端 Obsidian 中写普通笔记
  2. 通过自定义 Obsidian 插件一键发布到 GitHub 仓库 source/_posts/
  3. GitHub 自动触发博客构建并发布到 GitHub Pages
  4. 博客首页显示每日发文热力图,直观看到最近是否持续更新

第一期目标不是做完整后台,而是先把下面这条闭环做稳:

写笔记 -> 点发布 -> GitHub 收到文章 -> 博客自动更新 -> 首页热力图变化

2. 当前项目情况

当前博客仓库位于 D:\blog\blog,已有这些基础条件:

  1. 使用 Hexo
  2. 文章目录是 source/_posts
  3. 主题是 butterfly
  4. 远程仓库是 git@github.com:smashxx00/blog.git
  5. 主分支是 main
  6. 当前仓库里还没有正式的 .github/workflows 自动发布流程

这意味着博客代码已经在 GitHub 上,但“发文后自动构建并自动上线”这条链路仍需要补齐。

3. 第一期开启范围

第一期包含两条主线:

  1. Obsidian 发布插件
  2. 博客端自动构建与首页热力图

第一期必须交付的能力:

  1. 能在 Obsidian 中发布当前笔记
  2. 能从指定草稿文件夹中选择一篇笔记发布
  3. 插件自动补全缺失的 Hexo 文章头信息
  4. 插件将文章直接上传到博客仓库 source/_posts/
  5. GitHub 自动触发博客构建与发布
  6. 博客首页新增发文热力图模块
  7. 发布成功后,原笔记保留原地,只写回已发布标记
  8. 已发布笔记再次发布时支持覆盖更新远程文章

第一期明确不做:

  1. 手机端支持
  2. 图片自动上传图床
  3. 定时发布
  4. 删除远程文章
  5. 批量发布
  6. 独立写作后台
  7. 独立统计页
  8. 多仓库同时发布

4. 总体架构

整体链路如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sequenceDiagram
participant User as 你
participant Obsidian as Obsidian插件
participant GitHubAPI as GitHub接口
participant Repo as blog仓库 main分支
participant Actions as GitHub Actions
participant Pages as GitHub Pages
participant Site as 博客首页

User->>Obsidian: 写普通笔记并点击发布
Obsidian->>Obsidian: 读取笔记并补全文章信息
Obsidian->>GitHubAPI: 上传 source/_posts/文章.md
GitHubAPI->>Repo: 写入 main 分支
Repo->>Actions: 触发自动构建
Actions->>Pages: 发布静态站点
Pages->>Site: 首页文章与热力图更新

模块拆分如下:

  1. Obsidian 插件
    负责发布入口、读取笔记、转换文章、上传 GitHub、写回发布状态

  2. GitHub 文件上传层
    负责新建或覆盖 source/_posts/ 下的 Markdown 文件

  3. GitHub Actions 发布流程
    负责安装依赖、执行 hexo generate、发布到 GitHub Pages

  4. 首页热力图模块
    负责读取 Hexo 文章数据,统计每日发文数量,并在首页展示

5. Obsidian 插件设计

5.1 使用入口

第一期插件保留最少但够用的 3 个入口:

  1. 发布当前笔记
  2. 从草稿文件夹选择并发布
  3. 打开插件设置

其中最常用的是“发布当前笔记”。“从草稿文件夹选择并发布”用于从固定目录中挑选文章。

5.2 设置项

插件设置页第一期包含以下字段:

  1. GitHub owner
  2. GitHub repo
  3. branch
  4. 文章发布目录
  5. 草稿文件夹路径
  6. GitHub Token
  7. 发布后写回标记

默认建议值:

  1. branch = main
  2. 文章发布目录 = source/_posts
  3. 发布后写回标记 = 开启

5.3 Token 存储方式

GitHub Token 不写进普通配置文件,而是存到 Obsidian 的安全存储中。

普通设置里只保存:

  1. owner
  2. repo
  3. branch
  4. 草稿目录
  5. 文章目录

5.4 发布流程

1
2
3
4
5
6
7
8
9
flowchart TD
A[点击发布] --> B[读取当前笔记或草稿文件]
B --> C[解析 frontmatter 和正文]
C --> D[补齐缺失字段]
D --> E[生成目标文件名和发布路径]
E --> F[弹出发布确认]
F --> G[上传到 GitHub]
G --> H[写回已发布标记]
H --> I[提示博客正在自动更新]

发布确认弹窗显示:

  1. 标题
  2. 日期
  3. 摘要预览
  4. 标签
  5. 分类
  6. 目标路径
  7. 是否为覆盖更新

6. 笔记转 Hexo 文章规则

6.1 输入形式

插件兼容两种情况:

  1. 普通 Obsidian 笔记,没有完整文章头
  2. 已经带部分 frontmatter 的笔记

规则是:

  1. 用户已填写的字段优先保留
  2. 用户未填写的字段由插件自动补齐

6.2 字段优先级

字段生成规则如下:

  1. title
    优先级:frontmatter.title > 笔记文件名 > 正文第一行

  2. date
    优先级:frontmatter.date > 当前发布时间

  3. description
    优先级:frontmatter.description > 正文前 80 到 120 个字的自动摘要

  4. categories
    优先级:frontmatter.categories > frontmatter.category > 空

  5. tags
    优先级:frontmatter.tags > Obsidian 笔记标签 > 空

  6. cover
    如果用户已填写则保留;第一期不自动生成

  7. slug
    第一期不单独生成

6.3 文件名规则

发布文件名生成规则:

  1. 优先使用原笔记文件名
  2. 去掉非法字符
  3. 去掉多余空格
  4. 保留中文文件名
  5. 若远程已存在同名文件,则追加时间后缀

示例:

  1. Obsidian发布测试.md
  2. Obsidian发布测试-20260416-223000.md

6.4 正文处理规则

第一期插件尽量少改正文:

  1. 读取正文原文
  2. 去掉原 frontmatter
  3. 重新拼接标准 Hexo frontmatter
  4. 保留正文主体不变

第一期不做:

  1. 自动插入 <!-- more -->
  2. 自动改写图片路径
  3. 自动上传附件
  4. 自动重写 Markdown 内容

6.5 发布状态回写

发布成功后,原笔记保留在原位置,并写回以下字段:

1
2
3
4
published: true
published_at: 2026-04-16 22:35:00
github_path: source/_posts/Obsidian发布测试.md
github_sha: xxxxxxxxx

其中:

  1. published 表示已发布
  2. published_at 记录发布时间
  3. github_path 记录远程目标路径
  4. github_sha 用于后续覆盖更新

6.6 重复发布处理

若笔记已发布,再次点击发布时:

  1. 插件识别 published: true
  2. 提示该笔记已发布过
  3. 用户可选择“覆盖更新”或“取消”

第一期不做“每次重新生成一份新文章副本”。

7. GitHub 接入设计

7.1 接口方案

第一期插件不调用本地 git 命令,而是直接调用 GitHub 的文件接口上传文章。

选择这个方案的原因:

  1. 不依赖本机 git 状态
  2. 不依赖 SSH 配置是否正常
  3. 更适合之后扩展
  4. 更符合“一键发布”目标

7.2 Token 方案

建议使用 GitHub Fine-grained Personal Access Token,并限制到博客单仓库。

第一期需要的最小权限:

  1. Contents: Read and Write

其余权限不默认开启。

7.3 失败场景

插件需要明确区分并提示以下失败原因:

  1. Token 未配置
  2. owner/repo/branch 配置错误
  3. 权限不足
  4. 网络失败
  5. 文件冲突
  6. GitHub 接口返回错误
  7. 上传成功但博客构建失败

提示文案目标是直白说明问题,不使用含糊术语。

7.4 第一期开关边界

第一期插件只做:

  1. 新建远程文章
  2. 覆盖更新已发布文章

第一期不做:

  1. 删除远程文章
  2. 回滚历史版本
  3. 批量覆盖整个目录

8. GitHub Pages 自动发布设计

博客仓库需补齐 .github/workflows 自动发布流程。

目标链路:

1
2
3
4
5
6
7
8
9
10
11
12
sequenceDiagram
participant Plugin as Obsidian插件
participant Repo as blog main 分支
participant Actions as GitHub Actions
participant Hexo as Hexo
participant Pages as GitHub Pages

Plugin->>Repo: 提交新文章
Repo->>Actions: 触发 workflow
Actions->>Hexo: npm ci
Actions->>Hexo: hexo generate
Hexo->>Pages: 发布 public 产物

工作流第一期负责:

  1. 安装 Node 依赖
  2. 执行 hexo generate
  3. 将构建产物发布到 GitHub Pages

第一期插件只需要告诉用户:

  1. 文章已上传到 GitHub
  2. 博客正在自动更新

第一期不要求插件继续轮询 GitHub Actions 状态。

9. 首页热力图设计

9.1 放置位置

热力图第一期放在首页文章列表上方。

页面结构:

1
2
3
4
flowchart TD
A[首页头图] --> B[发文热力图模块]
B --> C[最近文章列表]
C --> D[分页]

选择该位置的原因:

  1. 首页打开即可看到发文活跃度
  2. 不压缩侧边栏空间
  3. 不需要额外新页面
  4. 更符合“持续输出”的展示目标

9.2 数据来源

热力图数据直接从 Hexo 文章数据中统计,不接数据库,不接外部服务。

统计口径:

  1. 以文章 date 字段为准
  2. 按天统计当天发文数量
  3. 生成近一年数据

9.3 模块内容

首页热力图模块第一期包含 3 个部分:

  1. 年度热力图
  2. 统计摘要
  3. 颜色深浅说明

统计摘要至少显示:

  1. 今年已发多少篇
  2. 当前连续更新多少天
  3. 最近一次更新日期

颜色层级建议:

  1. 0 篇:最浅
  2. 1 篇:浅色
  3. 2 篇:中等
  4. 3 篇及以上:最深

9.4 第一阶段不做

热力图第一期不做:

  1. 单独统计页
  2. 年份切换
  3. 分类筛选
  4. 标签筛选
  5. 阅读量或评论联动

10. 测试与验收

10.1 测试层次

第一期验证分为 4 层:

  1. 文章转换测试
    验证普通笔记能否正确转成 Hexo 文章

  2. GitHub 上传测试
    验证新建与更新文章是否正确

  3. 自动发布测试
    验证 GitHub Actions 和 Pages 是否自动更新

  4. 热力图显示测试
    验证首页热力图统计和布局是否正常

10.2 必测场景

至少覆盖以下场景:

  1. 无 frontmatter 的普通笔记发布
  2. 带部分 frontmatter 的笔记发布
  3. 中文标题和中文文件名发布
  4. 已发布笔记覆盖更新
  5. Token 错误提示
  6. 仓库配置错误提示
  7. 构建成功后首页文章更新
  8. 构建成功后首页热力图变化

10.3 完成标准

只有以下条件都满足,第一期才算完成:

  1. 能发布当前笔记
  2. 能从草稿文件夹选择一篇笔记发布
  3. 文章进入 source/_posts/
  4. GitHub Pages 自动更新
  5. 首页出现新文章
  6. 首页热力图因新文章发生变化
  7. 原笔记写回已发布标记
  8. 已发布笔记可再次覆盖更新
  9. 常见错误提示清楚

11. 推荐实现顺序

推荐开发顺序如下:

  1. 先补 GitHub Pages 自动发布流程
  2. 再实现博客首页热力图模块
  3. 再搭 Obsidian 插件设置页和 GitHub 连接层
  4. 实现“发布当前笔记”
  5. 实现“从草稿文件夹选择并发布”
  6. 实现“已发布标记”和“覆盖更新”
  7. 最后做整体验证

这样安排的原因:

  1. 先把博客端落点打通
  2. 再做可见展示结果
  3. 最后接入发文入口

12. 后续扩展方向

第一期做稳后,后续可以逐步增加:

  1. 手机端兼容
  2. 图片自动上传
  3. 定时发布
  4. 构建状态回传
  5. 独立统计页
  6. 分类与标签统计
  7. 更完整的文章管理面板

第一期不为了这些后续能力提前做过度设计,先优先保证当前闭环好用、稳定、可维护。