核心目标:
hugo.toml(根目录)不再放任何 menus 菜单代码,只保留站点基础配置、主题参数- 所有导航菜单统一放在
config/_default/menus.toml 单独维护 - 理解:这个场景下,
_merge = "deep" 可加,但它的作用是为以后再拆分追加配置留后路(文档 “合并必要配置” 的思想:按需拆分、按需合并,不写冗余配置) - 风险消失:不会出现多文件菜单互相覆盖
一、目录结构对照(最终状态)
1
2
3
4
5
| Hugo项目根目录
├── hugo.toml # 从主题复制过来的主配置 → 删除里面所有 [[menus.main]]
└── config/
└── _default/
└── menus.toml # ✅ 新建,存放全部菜单
|
二、详细步骤
1、新建文件
新建config/_default/menus.toml,如果 config/_default 文件夹不存在,手动新建两层文件夹 config → _default
2、打开根目录 hugo.toml
- 在 hugo.toml 里搜索所有以
[[menus.main]] 开头的段落 - 剪切:从
[[menus.main]] 一直到这个菜单对应的 [menus.main.params] 结束,一段一段全部剪出来
⚠️ 注意:连带子菜单(parent = "xxx" 的那些 [[menus.main]])一起剪切,不要漏
- 剪切完之后:hugo.toml 里面不能再留有任何
[menus] / [[menus.main]]
✅ hugo.toml 剩下:基础 baseURL、languageCode、theme、[params]、[outputs] 等,清爽干净
步骤 3:把剪切出来的所有菜单粘贴到 config/_default/menus.toml
文件最顶部第一行写上 _merge = "deep"
为什么这里明明只有一个菜单文件还要写? FixIt 文档「合并必要配置」的工程化思路: 现在虽然只有这一份菜单文件,未来如果你还想再拆分出第二个菜单配置文件追加菜单时,不需要再改这里的代码,提前规范写法。 如果不写,当前单文件场景也能正常运行,但不符合文档推荐的规范。
步骤 4:完整带注释的 menus.toml 模板(直接替换使用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
| # ==============================================
# _merge = "deep" 配置合并策略
# deep:深度合并,数组支持追加。遵循 FixIt 文档「合并必要的配置」规范
# 当前只有这一个菜单文件时写它是为了兼容未来扩展,防止后续新增配置被覆盖
# 可选值:deep / shallow / replace(默认replace)
# ==============================================
[menus]
_merge = "deep"
# --------------------------
# 一级主导航菜单
# identifier:全局唯一ID,子菜单依靠 parent 绑定这个ID,不能重复
# parent:留空 = 一级菜单;填写其他菜单的identifier,就变成子菜单
# name:菜单显示文字,支持简单HTML
# url:链接,站内写相对路径 /xxx/;外部链接写完整 https://
# weight:排序权重,数字越小,越靠前展示
# title:鼠标悬浮时的提示文字
# pre:在菜单名称之前添加内容,支持 HTML 不写或空字符串代表不加
# post:在菜单名称之后添加内容,支持 HTML 不写或空字符串代表不加
# --------------------------
[[menus.main]]
identifier = "home"
name = "首页"
url = "/"
weight = 1
[menus.main.params]
icon = "fa-solid fa-house" # FontAwesome图标
# class = "" # 自定义css类,不需要就留空或者删掉
# draft = false # 草稿菜单,true默认隐藏,调试用
# type = "" # mobile仅移动端 / desktop仅桌面端,空=两端都显示
[[menus.main]]
identifier = "archives"
parent = ""
pre = ""
post = ""
name = "归档"
url = "/archives/"
weight = 2
[menus.main.params]
class = ""
draft = false
icon = "fa-solid fa-box-archive"
type = ""
divided = false
[[menus.main]]
identifier = "tages"
parent = ""
pre = ""
post = ""
name = "标签"
url = "/tags/"
title = ""
weight = 3
[menus.main.params]
icon = "fa-solid fa-folder-tree"
[[menus.main]]
identifier = "categories"
name = "分类"
url = "/categories/"
weight = 4
[menus.main.params]
icon = "fa-solid fa-folder"
[[menus.main]]
identifier = "docs"
name = "文档"
url = "/docs/"
weight = 5
[menus.main.params]
icon = "fa-solid fa-book"
# --------------------------
# 子菜单:parent = 父菜单的 identifier(上面的docs)
# --------------------------
[[menus.main]]
identifier = "quickstart"
parent = "docs"
name = "快速上手"
url = "/docs/quick-start/"
weight = 1
[[menus.main]]
identifier = "config-intro"
parent = "docs"
name = "配置介绍"
url = "/docs/getting-started/configuration/introduction/"
weight = 2
[[menus.main]]
identifier = "theme-faq"
parent = "docs"
name = "常见问题"
url = "/docs/faq/"
weight = 3
[menus.main.params]
divided = true # 这个子项上方显示分割线,用来分组
[[menus.main]]
identifier = "customize"
parent = "docs"
name = "自定义修改"
url = "/docs/customization/"
weight = 4
# --------------------------
# 外部链接菜单示例
# --------------------------
[[menus.main]]
identifier = "github"
name = "GitHub"
url = "https://github.com/lruihao/hugo-theme-fixit"
weight = 6
[menus.main.params]
icon = "fa-brands fa-github"
# --------------------------
# 仅移动端汉堡菜单可见示例
# --------------------------
[[menus.main]]
identifier = "mobile-page"
name = "移动端专属"
url = "/mobile/"
weight = 7
[menus.main.params]
icon = "fa-solid fa-mobile-screen"
type = "mobile"
|
Hugo 原生菜单项(双层方括号,数组,每一个 [[ ]] 代表一条导航菜单)
[menus.main.params]:这条菜单的自定义参数表(单层方括号,属于这个菜单项的附加配置,是 FixIt 主题自己扩展的,不是 Hugo 原生)
步骤 5:验证 & 启动站点测试
三、关键知识点(对应文档「合并必要的配置」)
- Hugo 的机制:
config/_default/ 下面所有文件,会自动合并进站点配置 hugo.toml + config/_default/*.toml 是自动合并的,这是 Hugo 原生多配置文件能力 - 本方案中
_merge="deep" 的定位: 不是现在必须,而是工程规范预留。以后如果你想再新建一个文件 config/_default/menus-extra.toml 追加菜单,只要那个文件顶部也写 _merge="deep",菜单就会追加,不会覆盖全部。 - 「必要配置」的含义:
- hugo.toml:只放站点运行必要基础配置
- menus.toml:只放菜单这一类必要配置
- 不把所有配置全部堆在一个大文件里;不用的参数可以直接删掉,不要无脑复制主题全套默认配置
四、常见踩坑清单
- ❌ 剪切菜单的时候,漏剪了某个子菜单,菜单消失
- ❌ 剪切完 hugo.toml 还残留半截
[[menus.main]],Hugo 报解析错误 - ❌
identifier 重复,菜单渲染异常、随机消失 - ❌
parent 写错名字(大小写敏感!),子菜单不会挂载到父菜单,变成一级菜单 - ❌ 文件夹名字写错:
_default 前后是下划线,不能写成 default
五、后续新增菜单怎么操作
直接在 menus.toml 文件末尾追加 [[menus.main]] 块即可,不用动 hugo.toml。
04-带注释的 menus.toml 模板还没有使用,使用的是将主题下关于菜单,单独抽离出来
05-将菜单单独抽离出来