Hugo系统文章多层分类设计方法
1. 什么是多层分类?
在博客文章管理中,多层分类(Hierarchical Categories)是指将分类按照层级关系组织,类似于文件夹的树状结构:
机械设计(主分类)
├── 压力容器设计(子分类)
├── 仿真分析(子分类)
└── 传动系统(子分类)
技术教程(主分类)
├── 编程开发(子分类)
└── 开发工具(子分类)
1.1 为什么需要多层分类?
- 文章数量增多:平铺所有分类会显得杂乱无章
- 主题细分:同一大类下有多个细分领域
- 导航便利:读者可以按层级浏览感兴趣的内容
- 结构清晰:便于长期维护和管理
2. 实现原理
Hugo本身不直接支持树状分类,但我们可以通过命名约定和自定义模板实现多层分类效果:
2.1 核心思路
使用 主分类/子分类 的格式来表示层级关系:
这样Hugo会创建两个分类页面:
/categories/机械设计//categories/机械设计/压力容器设计/
然后通过自定义模板解析这种命名规则,在分类列表页展示层级关系。
3. 实现步骤
步骤1:配置Hugo支持分类
编辑 hugo.toml 文件,添加taxonomies配置:
# 配置分类法(支持多级分类)
[taxonomies]
category = "categories"
tag = "tags"
series = "series"
步骤2:修改文章Front Matter
在文章的front matter中使用数组形式定义分类:
示例1:压力容器设计类文章
+++
title = '分析设计法介绍'
date = '2026-01-24T19:10:38+01:00'
draft = false
# 同时属于"机械设计"和"机械设计/压力容器设计"
tags = ["压力容器", "分析设计", "DBA"]
summary = "这是一篇关于承压设备分析设计的入门简介..."
+++
示例2:编程教程类文章
+++
title = 'Python科学计算入门'
date = '2026-01-20T16:30:00+01:00'
draft = false
tags = ["Python", "NumPy", "编程", "科学计算"]
+++
步骤3:创建自定义分类模板
创建 layouts/_default/terms.html 文件:
{{- define "main" }}
{{- if .Title }}
<header class="page-header">
<h1>{{ .Title }}</h1>
{{- if .Description }}
<div class="post-description">
{{ .Description }}
</div>
{{- end }}
</header>
{{- end }}
{{- $type := .Type }}
{{- $terms := .Data.Terms }}
{{- /* 收集所有分类并分组 */ -}}
{{- $mainCategories := slice }}
{{- $subCategories := dict }}
{{- $categoryCount := dict }}
{{- range $key, $value := $terms.Alphabetical }}
{{- $name := .Name }}
{{- $count := .Count }}
{{- $categoryCount = merge $categoryCount (dict $name $count) }}
{{- if not (strings.Contains $name "/") }}
{{- $mainCategories = $mainCategories | append $name }}
{{- else }}
{{- $parts := split $name "/" }}
{{- $parent := index $parts 0 }}
{{- $subs := index $subCategories $parent | default slice }}
{{- $subs = $subs | append $name }}
{{- $subCategories = merge $subCategories (dict $parent $subs) }}
{{- end }}
{{- end }}
<div class="terms">
{{- range sort $mainCategories }}
{{- $mainCat := . }}
{{- $count := index $categoryCount $mainCat }}
{{- with site.GetPage (printf "/%s/%s" $type $mainCat) }}
{{- $mainCatURL := .Permalink }}
<div class="category-group">
<h2 class="main-category">
<a href="{{ $mainCatURL }}">{{ $mainCat }}</a>
<sup><strong>{{ $count }}</strong></sup>
</h2>
{{- /* 显示该主分类下的子分类 */ -}}
{{- $subs := index $subCategories $mainCat }}
{{- if $subs }}
<ul class="sub-categories">
{{- range sort $subs }}
{{- $subCat := . }}
{{- $subCount := index $categoryCount $subCat }}
{{- $parts := split $subCat "/" }}
{{- $subName := index $parts 1 }}
{{- with site.GetPage (printf "/%s/%s" $type $subCat) }}
<li>
<a href="{{ .Permalink }}">{{ $subName }}</a>
<sup>{{ $subCount }}</sup>
</li>
{{- end }}
{{- end }}
</ul>
{{- end }}
</div>
{{- end }}
{{- end }}
</div>
{{- end }}{{/* end main */}}
步骤4:添加CSS样式
创建 assets/css/extended/category-hierarchy.css 文件:
/* 多级分类样式 */
.category-group {
margin-bottom: 2rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid var(--border);
}
.category-group:last-child {
border-bottom: none;
}
.main-category {
font-size: 1.5rem;
margin-bottom: 0.8rem;
color: var(--primary);
}
.main-category a {
color: var(--primary);
text-decoration: none;
}
.main-category a:hover {
text-decoration: underline;
}
.main-category sup {
font-size: 0.8rem;
margin-left: 0.3rem;
color: var(--secondary);
}
.sub-categories {
list-style: none;
padding-left: 2rem;
margin: 0;
}
.sub-categories li {
margin: 0.5rem 0;
font-size: 1.1rem;
}
.sub-categories li a {
color: var(--content);
text-decoration: none;
transition: color 0.3s ease;
}
.sub-categories li a:hover {
color: var(--primary);
text-decoration: underline;
}
.sub-categories li sup {
font-size: 0.75rem;
margin-left: 0.3rem;
color: var(--secondary);
}
/* 移动端适配 */
@media (max-width: 768px) {
.sub-categories {
padding-left: 1rem;
}
.main-category {
font-size: 1.3rem;
}
.sub-categories li {
font-size: 1rem;
}
}
步骤5:测试效果
运行Hugo服务器:
hugo server -D
访问 http://localhost:1313/categories/ 查看分类页面效果。
4. 模板代码详解
4.1 核心逻辑
{{- $type := .Type }} // 获取类型(categories/tags)
{{- $terms := .Data.Terms }} // 获取所有分类数据
// 判断是否为子分类(包含"/")
{{- if not (strings.Contains $name "/") }}
// 主分类
{{- else }}
// 子分类,分割字符串获取父分类名
{{- $parts := split $name "/" }}
{{- $parent := index $parts 0 }}
{{- end }}
4.2 数据结构
模板维护三个数据结构:
- $mainCategories:主分类列表
["机械设计", "技术教程"] - $subCategories:子分类字典
{ "机械设计": ["机械设计/压力容器设计", "机械设计/仿真分析"], "技术教程": ["技术教程/编程开发"] } - $categoryCount:每个分类的文章数量
4.3 渲染流程
- 遍历所有主分类
- 显示主分类名称和文章数量
- 查找该主分类下的所有子分类
- 缩进显示子分类列表
5. 目录组织建议
5.1 按分类组织文件夹(推荐)
content/posts/
├── 机械设计/
│ ├── 分析设计法介.md
│ ├── 有限元分析基础.md
│ └── 齿轮设计计算.md
├── 压力容器/
│ ├── LBB技术.md
│ └── ASME规范设计.md
└── 技术教程/
├── Python科学计算.md
└── Git版本控制.md
这样做的好处:
- 文件管理更直观
- 便于批量操作
- 与分类逻辑一致
5.2 分类命名规范
主分类建议:
- 宽泛的领域名称
- 2-4个字为宜
- 例如:机械设计、技术教程、生活随笔
子分类建议:
- 具体的主题方向
- 3-6个字为宜
- 例如:压力容器设计、编程开发、开发工具
6. 常见问题
Q1: 文章必须同时属于主分类和子分类吗?
是的。为了让文章在主分类页面也能显示,需要同时指定:
Q2: 可以有多层嵌套吗(如三层)?
可以,但不推荐。两层分类已经足够清晰,过深的层级会增加复杂度:
# 理论上可行但不推荐
Q3: 子分类可以属于多个主分类吗?
不建议。为保持层级清晰,每个子分类应该只属于一个主分类。
Q4: 如何修改现有文章的分类?
批量修改可以使用脚本或文本编辑器的查找替换功能:
查找:
替换为:
Q5: PaperMod主题如何自动加载CSS?
PaperMod主题会自动加载 assets/css/extended/ 目录下的所有CSS文件,无需额外配置。
7. 高级技巧
7.1 自动统计主分类文章数
如果希望主分类的文章数包括所有子分类的文章,可以在模板中计算:
{{- $totalCount := $count }}
{{- $subs := index $subCategories $mainCat }}
{{- range $subs }}
{{- $subCount := index $categoryCount . }}
{{- $totalCount = add $totalCount $subCount }}
{{- end }}
7.2 添加分类图标
在CSS中为不同分类添加图标:
.main-category a::before {
content: "📁 ";
}
.sub-categories li a::before {
content: "📄 ";
}
7.3 折叠/展开子分类
添加JavaScript实现交互:
document.querySelectorAll('.main-category').forEach(function(cat) {
cat.addEventListener('click', function() {
const subList = this.nextElementSibling;
subList.classList.toggle('collapsed');
});
});
8. 完整示例
项目结构
myblog/
├── hugo.toml # Hugo配置
├── content/
│ └── posts/
│ ├── 机械设计/
│ │ └── 文章1.md
│ └── 技术教程/
│ └── 文章2.md
├── layouts/
│ └── _default/
│ └── terms.html # 分类模板
└── assets/
└── css/
└── extended/
└── category-hierarchy.css # 样式文件
文章示例
+++
title = '有限元分析基础'
date = '2026-01-15T10:30:00+01:00'
draft = false
tags = ["有限元", "FEA", "ANSYS"]
summary = "介绍有限元分析的基本原理..."
+++
# 文章内容
...
9. 最佳实践
- 分类不宜过多:主分类3-5个,每个主分类下2-4个子分类
- 命名统一规范:使用中文或英文,保持一致
- 定期整理:随着内容增加,适时调整分类结构
- 避免重复:同一主题不要创建多个相似分类
- 保持灵活:分类不是一成不变的,可以根据需要调整
10. 总结
多层分类系统让Hugo博客的内容组织更加清晰有序。通过:
- ✅ 使用
主分类/子分类命名约定 - ✅ 自定义terms.html模板解析层级
- ✅ 添加CSS美化展示效果
- ✅ 在front matter中正确配置分类
就能实现一个功能完善的多层分类系统。
11. 参考资源
希望这篇教程能帮助你更好地组织博客内容!如有问题,欢迎交流。