翻新博客 + 加书架

2026-05-22T00:00:00-05:00 | 3分钟阅读

@

起因

第一章搭好的博客是扁平的时间线——所有文章都在 content/posts/ 下,按时间倒序排列。这种结构很适合写日记或杂记,但是想要写长篇连载(比如复健笔记、菜谱、相机使用说明书)就会发现:

  • 同一系列的文章会被时间打散
  • 读者点进单篇看不到上下文,不知道还有别的章节
  • 我自己也容易忘了之前写到哪

所以我想加一个书架放在主页最上方,和"杂记"并列,每本书内部有章、节两层结构。

整体方案

Claude 看完 dream 主题的源码之后给出的方案是:

Hugo 自带 page bundle 结构能完美表达"书 → 章 → 节"三层关系。书是一个 branch bundle(带 _index.md 的目录),章是嵌套在书目录下的 branch bundle,节是章目录下的普通 .md 文件。

具体的内容目录:

content/books/
├── _index.md                  (书架根,渲染时跳过)
├── rehab/                     (一本书:复健笔记)
│   ├── _index.md
│   ├── chapter-01/
│   │   ├── _index.md          (章简介)
│   │   ├── section-01.md
│   │   └── section-02.md
│   └── chapter-02/
└── blog/                      (也可以"平结构"——章本身就是节)
    ├── _index.md
    ├── chapter-01.md          (没有节,章就是叶节点)
    └── chapter-02.md

自定义 book CSS 和 JS

因为 Hugo Dream 模板没有书架,所以需要Claude搓一个新的格式。

Claude 的解决方案是:

自己写一个 static/css/book.css,在 hugo.toml[params.advanced] 里通过 customCSS 加载。所有书架相关的样式(侧栏粘性、归档时间线、卡片样式、暗色模式微调、tooltip)都写进这一个文件。

book.css 最终大概 500 行,覆盖:

  • 书侧栏 sticky 行为 + 暗色模式背景调整
  • 首页书卡片 grid 布局 + 帖子卡片
  • /posts/ 归档按"年 → 月"两层分组
  • nav 桌面悬浮 tooltip(::after + attr(title)
  • Waline 评论框布局微调
  • Mastodon 评论区样式

JS 只写了一个:static/js/book-scrollspy.js。节阅读时右侧的 TOC 会跟随滚动高亮当前 H2/H3,用 IntersectionObserver 实现,约 60 行。

修复顶部 nav:sticky → fixed

dream 主题的 <nav> 用的是 position: sticky。本地预览没问题,但部署到线上后我发现往下滚几下 nav 就消失了。Claude 排查后说:

主题的 .flip-container 有一个写死的 height: calc(100vh - 80px - 2rem) 打破了 sticky 的滚动上下文。把 nav 改成 position: fixed,然后给 body 加一个 padding-top 可以修复。

最终 CSS:

body > nav {
  position: fixed !important;
  top: 0; left: 0; right: 0;
  z-index: 40;
  background-color: oklch(var(--b1));
  border-bottom: 1px solid oklch(var(--bc) / 0.12);
}
body { padding-top: 5rem; }
@media (min-width: 1024px) {
  body { padding-top: 6rem; }
}

修复颜色闪烁问题

日间模式下,每次切换页面会先黑一闪再变白。Claude 解释:

系统在暗色模式时,浏览器在 JS 加载完之前默认背景是黑色,然后 Alpine.js(defer 加载)才把网页切到 emerald(亮色),出现"黑一下→白"的闪烁。修法是在 <head> 顶部加一段同步执行的 inline script,比 Alpine 早一步把 class 和 data-theme 设到 <html> 上。

覆盖 layouts/partials/head.html,在文件开头加:

<script>
  (function() {
    var pref = localStorage.getItem('hugo-theme-dream-is-dark');
    var prefersDark = matchMedia('(prefers-color-scheme: dark)').matches;
    var isDark = pref === 'y' || (pref !== 'n' && prefersDark);
    document.documentElement.classList.add(isDark ? 'dark' : 'light');
    document.documentElement.setAttribute('data-theme', isDark ? 'forest' : 'emerald');
    document.documentElement.style.backgroundColor = isDark ? '#1a1a1a' : '#ffffff';
  })();
</script>

写作辅助脚本

最后让 Claude 帮我加了两个可以直接双击执行 .command 脚本:

脚本用途
2_new_book_section.command交互式选书、选章、新建节,自动生成 frontmatter,自动算 weight = max + 1,建好同名图片目录
5_book_images.command把书节配套图片目录里的原图压缩成 webp、按 <section>_pNN.webp 重命名、上传到 S3 图床、打印 centered-image shortcode 复制粘贴

加上之前已有的 1_new_post.command(新建杂记)、3_hugo_server.command(本地预览)、4_post_images.command(杂记图片)、6_deploy.command(部署),我只要集中精力写作就可以了,剩下的都双击对应的脚本实现自动化。

© 2025 - 2026 Leona的田园牧歌

🌱 Powered by Hugo with theme Dream.

关于我

Leona

  • 女的。
  • INFJ -> ENFJ 年纪大了变成E人了。
  • 长毛象链接点这里!
  • 做了九年数据科学家,但是每次管自己叫”科学家“,都很羞愧。职业+J人,习惯把日常生活数据化。
  • 玩了十几年相机,三十岁以前拍人像擅长无痕修图,三十岁以后拍动物植物大自然。
  • 厌倦城市,旅行目标大多是看动物。
  • 嘴太叼,不好吃宁愿饿着,还好手艺不错,不会饿死自己。
  • 没体能天赋,从小长跑最后一名,但是热爱运动,练过跑步、举铁、泰拳、网球、crossfit,现在重心转向功能性训练。
  • 现阶段人生目标是找个山头归隐,自给自足,田园牧歌,种菜养花,遛猫逗狗,养鸡喂牛。