加新文章、换样式、修构建,先看这份再下手。
三个边界
docs/—— 内容。所有 markdown / HTML 都在这里。themes/matery/—— 样式。EJS 模板、CSS、JS、静态资源。source/css/、source/js/、source/libs/、source/medias/、layout/*.ejs。tools/+scripts/—— 适配层。把 docs 喂给 hexo,把 hexo 渲染产物套上主题。
配置文件两份:根目录的 _config.yml 是 hexo 自己的;_config.matery.yml 是对主题 _config.yml 的覆盖。改主题的默认值就改后者,**不要直接改 themes/matery/_config.yml**,因为主题升级会覆盖。
source/ 和 public/ 都在 .gitignore 里,每次 CI 现生成。source/_posts/ 不要手动 commit,没有任何作用。
一次 push 之后发生了什么
按 .github/workflows/hexo.yml 的执行顺序:
python3 tools/sync-hexo.py—— 读docs/下所有.md/.html,套 front matter,写到source/_posts/,并现写现生成source/database/index.md、source/projects/index.md这类 landing page。front matter 里的date:取自 git log 最早提交时间。python3 tools/copy-vendor.py—— 复制根目录的 logo 和打赏图到主题 medias 目录。npx hexo generate—— 加载主题,按 permalink 规则把_posts里的文章渲染成public/YYYY/MM/DD/<slug>/index.html。期间跑scripts/下的三个 filter / helper。- CI 把
public/上传 GitHub Pages。 node tools/init-gitalk-issues.js给所有新文章预创建评论 issue。
tools/patch-theme.py 不是单独一步。它被 sync-hexo.py 末尾调用,对主题文件做小手术(追加 SEO meta、注入”相关文章”块、PV 计数器等)。
怎么改东西
写新文章。在 docs/<分类>/ 下放个 .md 或 <name>/index.md(page bundle)。front matter 可选,缺什么 sync-hexo 会从第一个 H1 补。.html 也支持,会被剥外壳后套主题。
要分类。docs/<分类>/_index.md 里写 title: "...",目录下所有文章就自动带上这个 category。中文分类名会出现在 /blog/categories/<title>/。
改专题页。docs/database/_index.md 只放分类名映射,正文真正生成在 tools/sync-hexo.py:491 的 create_database_landing_page() 里。改那段 200 行字符串就是改专题页正文。
更好的做法是抽到 tools/templates/database.md + 占位符替换,sync 阶段再渲染。
改菜单、副标题、打赏、Gitalk。_config.matery.yml。
加新组件、动主题布局。tools/patch-theme.py,按 section 编号找。
加 hexo 辅助函数。scripts/*.js 里 hexo.extend.helper.register('xxx', fn)。主题 EJS 里就能用 <%= xxx(arg) %>。
加 hexo filter。scripts/*.js 里 hexo.extend.filter.register('before_post_render', fn),能改文章渲染前的 HTML。
站内链接怎么写
- 跨文章:相对路径
./babelfish ddl已知限制.md。文件名跟docs/里一致就行,hexo 会自动转 permalink。 - 分类页:
/blog/categories/<分类名>/。 - 标签页:
/blog/tags/<标签名>/。 - 外部站:普通
https://链接。
不要写 /blog/2026/07/03/xxx/ 这种绝对 permalink。日期由 tools/sync-hexo.py:46 的 git_date() 决定,重算之后 URL 会变。
时区那个坑
sync-hexo.py:46 用 git log --format=%ai 拿时间,原样写进 front matter(带 +0800)。CI 容器 TZ=UTC,hexo 的 node_modules/hexo/dist/plugins/processor/common.js:51 又把它当 UTC 重新算一次并强行偏移到 Asia/Shanghai,结果 2026-07-27 10:40 +0800 会被算成 26 号。
修法是 sync 把 +0800 去掉写 wall-clock 字符串(2026-07-27 10:40:11),并把 _config.yml 的 timezone: 留空。等下次 PR 修。
同样要避开的
themes/matery/_config.yml:主题升级会冲掉。source/_posts/...:.gitignore拦着,commit 也推不上去,CI 还会重写。- 在
docs/写 hexo 模板语法(<% %>/<%- %>):docs 只该是裸内容。 - 在
tools/sync-hexo.py写 200 行专题页字符串又不抽到tools/templates/:难维护,编辑器也没高亮。
那些还在跑的工具
| 工具 | 干啥的 | 什么时候跑 |
|---|---|---|
tools/sync-hexo.py |
docs → hexo source | CI 第一步,本地 npm run sync |
tools/patch-theme.py |
给主题加小补丁 | CI 紧跟 sync 之后 |
tools/copy-vendor.py |
logo、打赏图复制到主题 | CI |
tools/init-gitalk-issues.js |
预创建 Gitalk issue | CI 末段 |
tools/add-tags.py |
从正文提取 tags 加到 front matter | 本地 |
tools/check-markdown.py |
校验 front matter、链接、格式 | 本地 / 预提交 |
tools/fix-markdown.py |
自动修一些格式问题 | 本地 |
tools/strip-text-fences.py |
清理误用的 \``text` 围栏 |
sync-hexo 里调用 |
tools/localize-cdn.py |
把主题 jsDelivr CDN 换成本地 | 首次部署 |
scripts/html-renderer.js |
处理 .html 文章 |
hexo filter |
scripts/mermaid.js |
渲染 Mermaid 图 | hexo filter |
scripts/smart-summary.js |
生成首页/分类页摘要 | hexo helper |