【前情提要】 Hugo 装好了,站点跑起来了,hugo.toml 也改好了。老周说:“明天装主题,PaperMod。你先把主题克隆下来,改改配置。”小林打开终端,敲下 git clone,以为一切顺利。

一、主题商城,挑花了眼

早上,小林打开 Hugo 官网的主题页面,准备挑一个主题。

他往下滚:

Ananke
PaperMod
Stack
Coder
Book
Terminal
LoveIt
Even

每个都有预览图,每个都挺好看。

小林点开 Stack,深色背景,卡片式布局,侧边栏有标签云、归档、搜索框。“这个好看。”

他又点开 LoveIt,粉色系,圆角卡片,评论区集成。“这个也好看。”

他又点开 Coder,极简黑白,代码高亮漂亮。“这个更适合技术博客。”

他纠结了十分钟,在三个主题之间反复横跳。

老周端着保温杯路过,看了一眼屏幕:“你搁这儿选妃呢?”

“周哥,主题太多了,我挑不好。”

“我让你选了吗?”老周说,“昨天不是说了,用 PaperMod。”

“但 Stack 更好看……”

“好看能当饭吃?”老周拉过椅子坐下,“你现在的目标是三天搭完博客,不是搭一个完美博客。PaperMod 配置简单,中文支持好,出问题容易搜到答案。Stack 好看,但你光配侧边栏就能配一天。”

小林还在犹豫。

老周补了一刀:“你再纠结十分钟,我就让你用默认主题,连 PaperMod 都没有。”

小林立刻关掉 Stack 的预览页:“PaperMod,就它了。”

二、安装 PaperMod:git clone 的正确姿势

“PaperMod 有两种安装方式。”老周说,“一种是 Git 子模块,一种是直接 clone。子模块对你来说太复杂,直接 clone。”

“在哪儿 clone?”

“进你的站点目录,在 themes/ 下面 clone。”

小林敲:

cd ~/myblog
git clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

输出:

Cloning into 'themes/PaperMod'...
remote: Enumerating objects: ...
Receiving objects: 100% ...

“下完了。”小林说。

“注意,git clone 的最后一个参数是目标路径。”老周说,“你写 themes/PaperMod,它就把主题放到 themes/PaperMod/ 目录下。如果你只写 themes/,它会把主题放到 themes/hugo-PaperMod/,目录名不一样,配置里写的主题名也得跟着变。”

小林记下:clone 路径 = themes/主题名,配置里写 theme = "主题名"。

“现在改配置。”老周说。

小林打开 hugo.toml:

nano hugo.toml

改成:

baseURL = 'http://localhost:1313/'
languageCode = 'zh-cn'
title = '小林的技术博客'
theme = 'PaperMod'

保存,退出。

“跑一下。”

hugo server

输出:

Web Server is available at http://localhost:1313/

浏览器刷新。

页面变了——不再是白板,而是一个极简的首页,顶部有导航栏,中间有站点标题,底部有版权信息。

“成了。”小林兴奋地说。

“别高兴太早。”老周说,“主题是装上了,但 PaperMod 有一堆配置项,你不配,它就用默认值。默认值很多是英文的、不符合中文阅读习惯的。你得配。”

三、PaperMod 配置:从“能看”到“能用”

老周让小林在 hugo.toml 下面继续加配置。

“先配基础参数。”

[params]
    description = "小林的技术博客,记录运维学习之路"
    author = "小林"
    defaultTheme = "auto"
    ShowReadingTime = true
    ShowShareButtons = true
    ShowPostNavLinks = true
    ShowBreadCrumbs = true
    ShowCodeCopyButtons = true
    ShowToc = true
    TocOpen = false

“一个一个解释。”老周说。

  • description:站点描述,会出现在首页和 SEO 元信息里。
  • author:作者名,出现在文章底部。
  • defaultTheme:auto 表示跟随系统主题,也可以写 light 或 dark。
  • ShowReadingTime:显示阅读时间。
  • ShowShareButtons:显示分享按钮。
  • ShowPostNavLinks:文章底部显示上一篇/下一篇。
  • ShowBreadCrumbs:显示面包屑导航。
  • ShowCodeCopyButtons:代码块右上角加复制按钮。
  • ShowToc:显示文章目录。
  • TocOpen:目录默认是否展开,false 表示折叠。

“先配这些,够用了。”老周说,“你再配菜单。”

在 hugo.toml 里加:

[menu]
    [[menu.main]]
        name = "首页"
        url = "/"
        weight = 10
    [[menu.main]]
        name = "归档"
        url = "/archives/"
        weight = 20
    [[menu.main]]
        name = "标签"
        url = "/tags/"
        weight = 30
    [[menu.main]]
        name = "关于"
        url = "/about/"
        weight = 40

“weight 是排序,越小越靠前。”老周说,“你保存,刷新看看。”

小林保存,浏览器刷新。导航栏出现了四个菜单:首页、归档、标签、关于。

“但点‘归档’和‘标签’是 404。”小林说。

“正常。”老周说,“archives 和 tags 页面需要模板,PaperMod 内置了,但你需要告诉 Hugo 生成这些页面。你在 content/ 下建两个文件。”

touch content/archives.md
touch content/tags.md

编辑 content/archives.md:

---
title: "归档"
layout: "archives"
url: "/archives/"
summary: archives
---

编辑 content/tags.md:

---
title: "标签"
layout: "tags"
url: "/tags/"
summary: tags
---

“保存,刷新,再点。”

小林刷新,点“归档”,页面出来了,按年份列出所有文章。点“标签”,标签云出现了。

“成了。”小林说。

四、中文配置:让 PaperMod 说中文

“现在配中文。”老周说,“PaperMod 默认英文,你要改几个地方。”

在 hugo.toml 里加:

[languages]
    [languages.zh]
        languageName = "中文"
        weight = 1
        title = "小林的技术博客"
        [languages.zh.params]
            description = "记录运维学习之路"

“但更简单的方式是直接改 languageCode。”老周说,“你已经写了 zh-cn,PaperMod 会自动识别。但有些文案,比如‘阅读时间’、‘上一篇’,是主题内置的翻译文件。PaperMod 自带中文翻译,你不用管。”

“那日期格式呢?”

“默认是英文格式,比如 September 13, 2026。你想改成 2026-09-13,在 hugo.toml 里加:”

[params]
    dateFormat = "2006-01-02"

“2006-01-02 是 Go 语言的时间格式,记住这个就行。”老周说,“你保存,刷新,文章日期就变了。”

五、首页配置:让首页有点“人样”

“首页现在是默认的,只有一个标题。”老周说,“你配一下首页。”

在 hugo.toml 里加:

[params.homeInfoParams]
    Title = "你好,我是小林"
    Content = "一名刚入行的运维工程师,正在学习 Linux、监控和日志分析。这里记录我的学习笔记和踩坑经历。"

“保存,刷新。”

首页出现了两行字:标题和简介。

“再加个社交图标。”老周说。

[[params.socialIcons]]
    name = "github"
    url = "https://github.com/yourname"
[[params.socialIcons]]
    name = "email"
    url = "mailto:your@email.com"

“这些图标会显示在首页和文章底部。”老周说,“你以后有 Twitter、LinkedIn,也可以加。”

小林点点头,把 GitHub 地址填了自己的。

六、排错挑战:hugo server 报错找不到主题

下午,小林想把主题目录改成 papermod(小写),他觉得小写看着舒服。

他执行:

mv themes/PaperMod themes/papermod

然后改 hugo.toml:

theme = 'papermod'

保存,运行:

hugo server

输出:

Error: module "papermod" not found; either add it as a Hugo Module or store it in "/home/devops/myblog/themes".: module does not exist

“啥?”小林懵了,“我明明把目录改成小写了啊。”

他检查目录:

ls themes/

输出:

papermod

“目录在啊,配置也改了,为啥找不到?”

他喊来老周。

老周看了一眼,问:“你改目录名之后,hugo.toml 里 theme 写的是 papermod?”

“对啊。”

“你 git clone 的时候,目录名是 PaperMod,大写。你改成小写,但 PaperMod 主题内部有些文件可能引用了 PaperMod 这个路径。Hugo 找主题时,是按目录名找的,但你改了小写,Hugo 在 themes/papermod 里找 papermod 主题,但主题的 theme.toml 里可能写的是 PaperMod。”

“那怎么办?”

“简单,改回大写。”老周说,“别没事改主题目录名。 你 clone 下来叫什么,就让它叫什么。配置里的 theme 和目录名完全一致就行。”

小林改回去:

mv themes/papermod themes/PaperMod

hugo.toml 改回:

theme = 'PaperMod'

再次运行,成功了。

排错思路总结:

  1. hugo server 报错 module "xxx" not found,先检查 themes/ 目录下主题是否存在。
  2. 检查 hugo.toml 中 theme 值是否和目录名完全一致(大小写敏感)。
  3. 如果改过目录名,改回去,别折腾。
  4. 如果目录名和配置都正确,检查主题是否完整(git clone 是否中断)。
  5. 最后检查 themesDir 配置(默认是 themes,一般不用改)。

“记住,”老周说,“主题目录名和 theme 配置,必须一模一样。大小写、连字符、下划线,都不能差。 你以后遇到‘找不到主题’,第一件事就是对比这两个。”

七、练习

  1. 练习一:在 Ubuntu 的 myblog 站点里,用 git clone 安装 PaperMod 主题到 themes/PaperMod。修改 hugo.toml,设置 theme = 'PaperMod',运行 hugo server,确认首页显示 PaperMod 默认样式。
  2. 练习二:在 hugo.toml 中添加 [params] 配置,设置 description、author、ShowReadingTime = true、ShowCodeCopyButtons = true。添加 [menu] 配置,创建“首页”“归档”“标签”“关于”四个菜单。创建 content/archives.md 和 content/tags.md,确认菜单点击不 404。
  3. 练习三:修改 [params.homeInfoParams],把首页标题改为“你好,我是你的名字”,内容改为一句你喜欢的话。添加一个 GitHub 社交图标,链接到你的 GitHub 主页(如果没有,随便填一个)。

参考答案

练习一:

cd ~/myblog
git clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
nano hugo.toml

修改:

theme = 'PaperMod'
hugo server

访问 http://localhost:1313,确认 PaperMod 样式生效。

练习二:

hugo.toml 添加:

[params]
    description = "小林的技术博客"
    author = "小林"
    ShowReadingTime = true
    ShowCodeCopyButtons = true

[menu]
    [[menu.main]]
        name = "首页"
        url = "/"
        weight = 10
    [[menu.main]]
        name = "归档"
        url = "/archives/"
        weight = 20
    [[menu.main]]
        name = "标签"
        url = "/tags/"
        weight = 30
    [[menu.main]]
        name = "关于"
        url = "/about/"
        weight = 40

创建归档和标签页:

touch content/archives.md content/tags.md

content/archives.md:

---
title: "归档"
layout: "archives"
url: "/archives/"
summary: archives
---

content/tags.md:

---
title: "标签"
layout: "tags"
url: "/tags/"
summary: tags
---

练习三:

hugo.toml 添加:

[params.homeInfoParams]
    Title = "你好,我是小林"
    Content = "一名刚入行的运维工程师,正在学习 Linux、监控和日志分析。"

[[params.socialIcons]]
    name = "github"
    url = "https://github.com/yourname"

保存,hugo server,刷新首页。

八、下集预告

主题装好了,菜单配好了,首页也有“人样”了。老周说:“明天写第一篇文章。”小林打开 hugo new,准备大展身手。但他不知道,YAML front matter 的缩进、draft 的坑、_index.md 和 index.md 的区别,正在前面等着他。

下一集:《写第一篇文章,结果被 YAML 头搞了半小时》