前言
这篇是 Drifting-PaperMod 指南系列的第一篇,目标不是把某一个细节讲到最深,而是先把整条主线跑通:准备环境、初始化站点、接入主题、整理内容结构、写出第一篇文章、确认本地可用,再部署到 Cloudflare Pages。
Moments 这篇会先讲最小可用结构,标签筛选、评论联动和交互细节后面再单独展开。
Step 1 - 准备工作
先确认这台机器上有没有现成的 Git 和 Hugo,再决定要不要安装或升级。当前主题要求:
text
1Hugo Extended >= 0.146.0先执行:
bash
1git --version
2hugo version如果 git --version 能正常输出,说明 Git 已经在本机可用。
如果 hugo version 输出里带有 extended,并且版本不低于 0.146.0,就可以直接继续后面的步骤,不一定要重新安装。
只有在下面这些情况里,才需要安装或升级:
- Git 命令不存在
- Hugo 命令不存在
- Hugo 不是
extended版 - Hugo 版本低于
0.146.0
安装或升级 Git
macOS:
bash
1xcode-select --installWindows:
powershell
1winget install --id Git.Git -e --source wingetLinux:
bash
1sudo apt install git如果你的 Linux 发行版不是 Debian / Ubuntu 系,把它换成自己发行版的包管理器命令即可。
安装或升级 Hugo
macOS:
bash
1brew install hugoWindows:
powershell
1winget install Hugo.Hugo.ExtendedLinux:
bash
1sudo snap install hugo如果已经安装过 Hugo,但版本太低或不是 Extended 版,也可以直接升级:
- macOS:
brew upgrade hugo - Windows:
winget upgrade Hugo.Hugo.Extended - Linux:使用当前发行版的包管理器升级对应包
处理完后,再执行一次:
bash
1git --version
2hugo version如果终端提示找不到 hugo,优先检查 PATH 和实际调用位置:
- macOS / Linux:
which hugo - Windows PowerShell:
Get-Command hugo
Step 2 - 初始化 Hugo 站点
先创建站点,再初始化 Git 仓库:
bash
1hugo new site myblog
2cd myblog
3git init这里的 git init 不只是为了后面提交代码,更是为了下一步接入 submodule。没有 Git 仓库,git submodule add 就不会工作。
接着先创建一篇测试文章:
bash
1hugo new content posts/hello-world/index.md我推荐从一开始就使用“一篇内容一个目录”的结构:
text
1content/
2└── posts/
3 └── hello-world/
4 └── index.md这样后面放图片、附件、音频会更自然。
Step 3 - 用 Submodule 接入 Drifting-PaperMod
站点初始化好之后,直接按主题 README 的方式接入:
bash
1git submodule add --depth=1 https://github.com/DriftingBoats/Drifting-PaperMod.git themes/Drifting-PaperMod
2git submodule update --init --recursive然后启用主题。Hugo 默认会生成 hugo.toml,如果你更习惯 YAML,也可以改成 hugo.yaml:
yaml
1theme:
2 - Drifting-PaperMod为什么这里推荐 submodule,而不是把主题代码直接拷进仓库?
- 主题和站点仓库边界更清楚
- 更新主题时不会把一堆主题文件混进正文提交
- 换电脑或多人协作时,初始化流程更明确
如果你在另一台电脑上拉仓库,最省事的方式是:
bash
1git clone --recurse-submodules <your-repo-url>如果仓库已经 clone 下来了,但 themes/Drifting-PaperMod 是空的,就补这一句:
bash
1git submodule update --init --recursiveStep 4 - 先配一套能长期用的 hugo.yaml
首篇不建议一上来就把所有参数都写满,但也不要只留一个 theme:。比较稳妥的做法,是先配一套足够完整、后面还能继续扩展的骨架。
下面这份配置片段已经覆盖了站点标题、首页介绍、菜单、社交图标、文章目录、滚动按钮和搜索所需的 JSON 输出:
yaml
1baseURL: https://example.com/
2languageCode: zh-cn
3title: My Blog
4
5theme:
6 - Drifting-PaperMod
7
8params:
9 mainSections:
10 - posts
11
12 title: My Blog
13 author: Your Name
14
15 showtoc: true
16 tocopen: true
17 disableScrollToTop: false
18
19 homeInfoParams:
20 Title: "你好,欢迎来到我的博客"
21 Content: 这里放一句首页简介。
22
23 label:
24 text: "My Blog"
25 icon: /img/200x200.png
26 iconHeight: 35
27
28 assets:
29 favicon: /img/16x16.png
30 favicon16x16: /img/16x16.png
31 favicon32x32: /img/32x32.png
32 apple_touch_icon: /img/200x200.png
33
34 socialIcons:
35 - name: github
36 url: https://github.com/yourname
37 - name: rss
38 url: /index.xml
39
40menu:
41 main:
42 - identifier: archives
43 name: 文章
44 url: /archives/
45 weight: 20
46 - identifier: search
47 name: 搜索
48 url: /search/
49 weight: 30
50
51outputs:
52 home:
53 - HTML
54 - RSS
55 - JSON这里最值得先记住的是:
params.mainSections决定首页和归档页主要使用哪些内容类型homeInfoParams是首页介绍区label和assets负责站点标识和 faviconshowtoc与tocopen控制文章目录outputs.home里的JSON是搜索页工作的前提
再补上搜索页和归档页
Drifting-PaperMod 已经自带搜索页和归档页布局,但你还需要在 content/ 下创建对应页面。
content/search.md:
yaml
1---
2title: 搜索
3layout: search
4menu: main
5weight: 99
6ShowBreadCrumbs: false
7---content/archives.md:
yaml
1---
2title: 文章
3layout: archives
4summary: archives
5menu: main
6weight: 30
7---这样菜单、搜索页和归档页才会真正串起来。
Step 5 - 内容结构:Posts、Moments 与 Front Matter
接好主题之后,最容易乱掉的不是配置,而是内容结构。把 posts、moments、页面文件和资源放置方式先定下来,后面写内容会轻松很多。
推荐的项目整体结构
一个和这套主题比较匹配的结构大致是这样:
text
1myblog/
2├── content/
3│ ├── posts/
4│ │ ├── _index.md
5│ │ └── my-first-post/
6│ │ ├── index.md
7│ │ └── cover.png
8│ ├── moments/
9│ │ ├── _index.md
10│ │ └── 260310-200410/
11│ │ ├── index.md
12│ │ └── Pasted image 20260310200413.jpg
13│ ├── search.md
14│ └── archives.md
15├── static/
16│ └── img/
17├── themes/
18│ └── Drifting-PaperMod/
19└── hugo.yaml这里可以这样理解:
content/posts/放普通文章content/moments/放 moments 内容content/search.md和content/archives.md分别对应搜索页和归档页static/img/放全站复用资源themes/Drifting-PaperMod/是主题 submodulehugo.yaml是站点总配置入口
posts/_index.md 和 moments/_index.md
在这套结构里,两个 _index.md 分别负责不同的 section。
content/posts/_index.md:
yaml
1---
2title: "文章"
3layout: posts
4summary: posts
5---这个文件负责文章列表页。
content/moments/_index.md:
yaml
1---
2title: 瞬间
3build:
4 render: always
5cascade:
6 - build:
7 list: local
8 publishResources: true
9 render: never
10menu: main
11weight: 10
12---这个文件负责 moments 列表页,同时决定子页面不单独渲染,但资源继续发布。
Posts 怎么组织
普通文章建议统一使用 leaf bundle:
text
1content/posts/my-first-post/
2├── index.md
3└── cover.png这种结构的好处是内容和资源天然绑定,迁移、备份和后续压缩图片都更方便。
Moments 怎么组织
Moments 也推荐使用同样的 leaf bundle 结构:
text
1content/moments/260310-200410/
2├── index.md
3└── Pasted image 20260310200413.jpg如果是音频或视频,也直接和 index.md 放在同一目录:
text
1content/moments/250625-154957/
2├── index.md
3└── M5000034UIUo36zCqC.mp3主题里的 layouts/moments/list.html 会直接渲染 content/moments/ 下的 .RegularPages,所以这种目录结构最省心。
普通文章的 Front Matter
对于普通文章,我建议直接按这套字段起步:
yaml
1---
2title: 我的第一篇文章
3slug: my-first-post
4date: 2026-03-10T22:00:00+08:00
5lastmod: 2026-03-10T22:00:00+08:00
6tags:
7 - Hugo
8categories: 博客建站
9series: Drifting-PaperMod 指南
10summary: 这里是一段文章摘要。
11draft: true
12---最关键的字段是:
titleslugdatedraft
如果按这个仓库的习惯继续完善,常用字段还包括:
lastmodtagscategoriesseriessummary
正式发布前,再把 draft: true 改成 draft: false。
Moments 的 Front Matter
单条 moment 通常不需要 title,更常见的是这种更轻量的写法:
yaml
1---
2date: 2026-03-10T20:04:10+08:00
3lastmod: 2026-03-10T20:04:14+08:00
4slug: 260310-200410
5tags:
6 - 杂记
7---Step 6 - 本地验证这套主题有没有真的接好
别急着上线,先把本地验证做完。
启动开发服务器:
bash
1hugo server -D至少检查这几类页面:
- 首页是否正确显示站点标题、首页简介和菜单
- 文章页是否能正常渲染正文和目录
/search/是否能打开/archives/是否能按时间归档文章/moments/是否能正常显示 moments 列表
最后再跑一次生产构建:
bash
1hugo --gc --minify如果这一步能正常生成 public/,说明这套 Hugo + 主题基础链路已经通了。
Step 7 - 主题维护:怎么更新 Drifting-PaperMod
如果主题仓库后面有更新,不需要删除主题目录重装,正常更新方式就是:
bash
1git submodule update --remote --merge themes/Drifting-PaperMod
2git add themes/Drifting-PaperMod
3git commit -m "theme: update Drifting-PaperMod"
4git push更新前我建议先看一下当前状态:
bash
1git status
2git submodule status --recursive更新主题时最容易踩的坑
1. 不要长期直接改 submodule 里的文件
如果你直接在 themes/Drifting-PaperMod 里改模板、样式和脚本,后面更新时会更容易冲突,也更容易把自己的改动弄丢。
更稳妥的做法是:
- 站点级覆盖优先放根目录自己的
layouts/、assets/、static/ - 如果确实要长期维护主题本体改动,先 fork 一份自己的主题仓库,再把 submodule 指向自己的 fork
2. 更新前先保证工作区干净
如果主仓库或 submodule 里本来就有未提交改动,更新后很难判断哪些是上游更新,哪些是自己的本地改动。
3. 更新后同步检查 Hugo 版本
主题 README 当前写的是 Hugo Extended >= 0.146.0。如果主题后续抬高要求,而你本地或部署环境还停在旧版本,就可能出现模板函数不兼容或构建失败。
4. 更新后一定先本地构建
先跑:
bash
1hugo server -D
2hugo --gc --minify确认首页、文章页、搜索页、归档页和 moments 页都正常,再 push。
Step 8 - 上线方式:部署到 Cloudflare Pages
本地确认没有问题后,再接 GitHub 和 Cloudflare Pages。
先把站点推到 GitHub:
bash
1git add .
2git commit -m "init: create Hugo site"
3git branch -M main
4git remote add origin https://github.com/<your-username>/<your-repo>.git
5git push -u origin main然后在 Cloudflare Pages 里导入这个 GitHub 仓库,使用最小可用配置:
- Production branch:
main - Build command:
hugo - Build directory:
public
同时在项目环境变量里手动设置:
text
1HUGO_VERSION=0.157.0Production 和 Preview 两边都建议配上,不要只配一个环境。
Build command 可以写成 hugo -b $CF_PAGES_URL,因为 Hugo 的 baseURL 会影响绝对链接和 canonical URL。对还没绑定正式域名,或者很依赖预览环境的站点,这个写法更稳。
如果你启用了首页热力图,也不需要再在 Cloudflare Pages 的构建命令里额外追加 pip install 或 python heatmap.py。当前热力图数据已经在 hugo 构建阶段由模板直接生成,保持纯 Hugo 构建即可。
后面还可以继续补什么
这篇先把主题首篇最关键的主线跑通,后面再往上叠功能会更自然。下一批适合单独展开的主题能力有:
- Moments 页面交互
- Waline 评论
- 首页热力图
- 常用 Shortcodes