【前情提要】
主题装好了,菜单配好了,首页也有“人样”了。老周说:“明天写第一篇文章。”小林打开 hugo new,准备大展身手。但他不知道,YAML front matter 的缩进、draft 的坑、_index.md 和 index.md 的区别,正在前面等着他。
一、老周的任务:写一篇博客
早上到工位,老周丢过来一句话:
“博客搭好了,你得往里写东西。今天写一篇,标题自拟,内容不限,但必须包含:一级标题、二级标题、代码块、图片、列表。”
“就这?”
“就这。”老周说,“但你写完得让它在首页显示出来,还得能通过标签和归档找到。你试试。”
小林觉得挺简单。他打开 SSH,连上 Ubuntu,进入站点目录。
cd ~/myblog
然后敲:
hugo new posts/my-first-post.md
输出:
Content "/home/devops/myblog/content/posts/my-first-post.md" created
“生成了。”小林打开文件:
nano content/posts/my-first-post.md
内容:
---
title: "My First Post"
date: 2026-09-13T10:00:00+08:00
draft: true
---
“就一个头?”小林说,“正文呢?”
“你自己写。”老周说,“front matter 是 Hugo 的‘文章头’,里面写元信息。正文在下面,用 Markdown 写。”
小林在 --- 下面加了一段:
# 我的第一篇博客
大家好,我是小林。今天我开始写博客了。
## 为什么写博客
因为老周说,运维要学会记录。
## 今天学了什么
- Hugo 安装
- PaperMod 主题配置
- Nginx 还没学
```bash
hugo version
```
保存,退出,运行:
hugo server
打开浏览器,访问 http://localhost:1313。
首页空白。
“嗯?”小林刷新了一下。还是空白。
他打开 http://localhost:1313/posts/my-first-post/。
输出:
404 page not found
“啥情况?”小林懵了,“我明明写了啊。”
二、draft: true:Hugo 的“草稿箱”
老周端着保温杯走过来,看了一眼屏幕:“你 front matter 里 draft 写的啥?”
小林打开文件:
---
title: "My First Post"
date: 2026-09-13T10:00:00+08:00
draft: true
---
“draft: true 啊。”小林说。
“那不就得了。”老周说,“draft: true 表示这是草稿,Hugo 默认不发布草稿。你 hugo server 不加参数,草稿不显示。”
“那怎么显示?”
“两种方式。”老周竖起两根手指。
方式一:改 draft 为 false。
draft: false
方式二:hugo server 加 -D 参数。
hugo server -D
“-D 表示 --buildDrafts,构建时包含草稿。你本地开发用这个方便,不用每次都改 draft。”
小林改成 draft: false,刷新。
文章出来了。
“记住了。”老周说,“draft: true 是草稿,不发布。draft: false 是正式文章,发布。 你以后写完文章,想先存着不发,就保持 true。想发,就改 false。”
小林在笔记本上写下:
draft: true→ 草稿,不发布draft: false→ 正式,发布hugo server -D→ 本地预览包含草稿
三、front matter:文章的“身份证”
“既然讲到 front matter,我就给你讲全。”老周说,“Hugo 的 front matter 有三种格式:YAML、TOML、JSON。你用的是 YAML,也是最常用的。”
“YAML 有啥特点?”
“缩进敏感。”老周说,“YAML 用空格缩进,不能用 Tab。 你复制网上代码的时候,经常混进 Tab,一混就报错。”
小林记下:YAML 只能用空格,不能用 Tab。
“常用的 front matter 字段有这些。”老周在纸上写:
---
title: "文章标题"
date: 2026-09-13T10:00:00+08:00
draft: false
tags: ["Linux", "Hugo"]
categories: ["运维"]
author: "小林"
description: "文章摘要,用于 SEO"
---
“一个一个说。”
title:文章标题,显示在页面顶部和列表里。date:发布日期,格式是YYYY-MM-DDTHH:MM:SS+时区。你写2026-09-13也行,Hugo 会补全。draft:草稿标记,true或false。tags:标签,数组格式,用["标签1", "标签2"]。categories:分类,也是数组。author:作者,会覆盖站点配置里的作者。description:摘要,出现在首页列表和 SEO 元信息里。
“你把这几个填上。”老周说。
小林改成:
---
title: "我的第一篇博客"
date: 2026-09-13T10:00:00+08:00
draft: false
tags: ["Hugo", "博客"]
categories: ["运维"]
author: "小林"
description: "小林的第一篇博客,记录 Hugo 搭建过程。"
---
保存,刷新。文章标题变成“我的第一篇博客”,底部出现“Hugo”“博客”两个标签,以及“运维”分类。
“点标签和分类看看。”
小林点“Hugo”标签,跳转到 /tags/hugo/,里面列出了这篇文章。
“成了。”小林说。
四、Markdown 正文:Hugo 的“写作语言”
“front matter 搞定了,正文你会写吧?”老周问。
“会一点。”小林说,“大学写过 Markdown。”
“那你写给我看看。一级标题、二级标题、代码块、图片、列表,都写一遍。”
小林在 front matter 下面写:
# 我的第一篇博客
大家好,我是小林。今天我开始写博客了。
## 为什么写博客
因为老周说,运维要学会记录。
## 今天学了什么
- Hugo 安装
- PaperMod 主题配置
- Nginx 还没学
## 代码示例
```bash
hugo version
```
## 图片

保存,刷新。
标题正常,列表正常,代码块正常,图片挂了。
“图片呢?”小林看着那个裂开的图标。
“你图片放哪了?”
“我没放。”
老周叹了口气:“Markdown 里的图片路径,是相对于 static/ 目录的。你写 /images/hugo-logo.png,就得把图片放在 static/images/hugo-logo.png。你没放,当然挂。”
小林把一张图片下载下来,放到 static/images/ 目录:
mkdir -p static/images
cp ~/Downloads/hugo-logo.png static/images/
刷新,图片出来了。
“记住了。”老周说,“Hugo 的静态文件放 static/,Markdown 里用 / 开头的绝对路径引用。 比如 static/images/hugo-logo.png,引用就是 /images/hugo-logo.png。”
小林在笔记本上写下:
- 图片、CSS、JS 放
static/ - Markdown 引用路径:
/images/xxx.png - 不要用
../相对路径,容易乱
“还有一个坑。”老周说,“路径大小写敏感。 你图片叫 Hugo-Logo.png,引用写 /images/hugo-logo.png,Linux 下直接 404。Ubuntu 是大小写敏感的,Mac 默认不敏感。你在 Mac 上写博客,图片能显示,传到 Ubuntu 就挂了。”
小林心里一紧,赶紧把图片名改成全小写。
五、文章目录:_index.md 和 index.md
“文章写完了。”小林说,“但我发现一个问题。”
“啥问题?”
“我在 content/posts/ 下写了文章,但我访问 http://localhost:1313/posts/ 是 404。只有直接访问 http://localhost:1313/posts/my-first-post/ 才行。”
老周笑了:“你发现了一个经典问题。Hugo 里,content/posts/ 是一个‘节(section)’。你想让 posts/ 有一个列表页,得在里面放一个 _index.md。”
“_index.md 和 index.md 啥区别?”
“这是 Hugo 最容易搞混的地方。”老周说,“我给你列一下。”
_index.md:表示这个目录是一个“节(section)”,会生成列表页。/posts/会显示这个节下所有文章的列表。index.md:表示这个目录是一个“页面(page)”,不会生成列表。/about/是一个独立页面,不需要列表。
“所以你访问 /posts/ 是 404,因为 posts/ 下没有 _index.md。”
“那怎么建?”
nano content/posts/_index.md
内容:
---
title: "文章"
date: 2026-09-13T10:00:00+08:00
draft: false
---
保存,刷新。访问 http://localhost:1313/posts/,出现了文章列表。
“成了。”小林说。
“记住:”
content/posts/_index.md→posts节的列表页content/about/index.md→about独立页面content/about.md→ 也是独立页面,但和about/index.md只能选一个
“再教你一个技巧。”老周说,“页面(index.md)可以有自己的资源目录。 比如 content/about/index.md 旁边可以放 content/about/photo.jpg,Markdown 里用 photo.jpg 直接引用,不用放 static/。这叫 Page Bundle,你以后写图文并茂的文章可以用。”
小林记下:列表页用 _index.md,独立页面用 index.md。
六、排错挑战:文章不显示
下午,小林想再写一篇文章,但写完 hugo server 之后,首页还是不显示。
他检查了:
draft: false✓date是当前日期 ✓- 文件在
content/posts/下 ✓
但文章就是不显示。
他打开 hugo server 的输出,发现一行黄色警告:
WARN found no layout file for "html" for kind "page": You should create a template file which matches Hugo Layouts Lookup Rules for this content.
“layout 是啥?”小林不懂。
他喊来老周。
老周看了一眼:“你文件名是不是带空格了?”
小林检查:
ls content/posts/
输出:
my first post.md
my-first-post.md
“你第一个文件名带了空格。”老周说,“Hugo 对文件名有要求,尽量用连字符 -,别用空格、中文、大写字母。”
“那我改成 my-first-post.md?”
“对。”老周说,“文件名只用小写字母、数字、连字符。 这是 URL 的一部分,大写和空格会被转义,很丑,还容易出问题。”
小林改名:
mv "content/posts/my first post.md" content/posts/my-first-post.md
刷新,文章出来了。
排错思路总结:
- 文章不显示,先检查
draft是否为false。 - 检查
date是否合法(不能是未来日期,除非--buildFuture)。 - 检查文件是否在
content/目录下。 - 检查文件名是否包含空格、大写、中文——建议全小写、连字符。
- 如果
hugo server输出found no layout file,检查主题是否完整、theme配置是否正确。 - 最后检查
hugo.toml里是否disableKinds = ["page"]之类的配置。
“记住,”老周说,“Hugo 的文件名,就是 URL。 你文件名写 My First Post.md,URL 就是 /posts/my-first-post/(转义后)。你写 my-first-post.md,URL 就是 /posts/my-first-post/。干净、可读、不出错。”
七、练习
- 练习一:用
hugo new posts/my-first-post.md创建文章,修改 front matter:title为“我的第一篇博客”,draft为false,tags为["Hugo", "博客"],categories为["运维"]。在正文里写一级标题、二级标题、列表、代码块。运行hugo server,确认首页显示文章,标签和分类可点击。 - 练习二:在
static/images/下放一张图片(可以从网上下载),在文章中用引用。确认hugo server渲染后图片显示。 - 练习三:创建
content/posts/_index.md,设置title: "文章"。访问http://localhost:1313/posts/,确认出现文章列表。然后创建content/about/index.md,设置title: "关于",写一段自我介绍,访问http://localhost:1313/about/,确认页面显示。
参考答案
练习一:
hugo new posts/my-first-post.md
nano content/posts/my-first-post.md
front matter:
---
title: "我的第一篇博客"
date: 2026-09-13T10:00:00+08:00
draft: false
tags: ["Hugo", "博客"]
categories: ["运维"]
---
正文:
# 我的第一篇博客
大家好,我是小林。
## 今天学了什么
- Hugo 安装
- PaperMod 主题配置
## 代码示例
```bash
hugo version
```
hugo server
访问 http://localhost:1313,确认文章显示。点击“Hugo”标签,跳转到 /tags/hugo/。
练习二:
mkdir -p static/images
cp ~/Downloads/hugo-logo.png static/images/
文章中添加:

刷新,图片显示。
练习三:
nano content/posts/_index.md
内容:
---
title: "文章"
date: 2026-09-13T10:00:00+08:00
draft: false
---
mkdir -p content/about
nano content/about/index.md
内容:
---
title: "关于"
date: 2026-09-13T10:00:00+08:00
draft: false
---
我是小林,一名刚入行的运维工程师。
访问 http://localhost:1313/posts/ 和 http://localhost:1313/about/,确认页面正常。
八、下集预告
文章写好了,标签配好了,列表页也有了。老周说:“明天让博客有点‘人样’,加图片、代码块、短代码。”小林打开 PaperMod 文档,准备大干一场。但他不知道,Hugo 的 shortcode、代码高亮、TOC,每一个都有细节。
下一集:《让博客有点“人样”:图片、代码块和短代码》