全部菜单迁移到独立

目录

核心目标:

  1. hugo.toml(根目录)不再放任何 menus 菜单代码,只保留站点基础配置、主题参数
  2. 所有导航菜单统一放在 config/_default/menus.toml 单独维护
  3. 理解:这个场景下,_merge = "deep" 可加,但它的作用是为以后再拆分追加配置留后路(文档 “合并必要配置” 的思想:按需拆分、按需合并,不写冗余配置)
  4. 风险消失:不会出现多文件菜单互相覆盖

一、目录结构对照(最终状态)

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

  1. 在 hugo.toml 里搜索所有以 [[menus.main]] 开头的段落
  2. 剪切:从 [[menus.main]] 一直到这个菜单对应的 [menus.main.params] 结束,一段一段全部剪出来

⚠️ 注意:连带子菜单(parent = "xxx" 的那些 [[menus.main]])一起剪切,不要漏

  1. 剪切完之后: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:验证 & 启动站点测试

三、关键知识点(对应文档「合并必要的配置」)

  1. Hugo 的机制:config/_default/ 下面所有文件,会自动合并进站点配置 hugo.toml + config/_default/*.toml 是自动合并的,这是 Hugo 原生多配置文件能力
  2. 本方案中 _merge="deep" 的定位: 不是现在必须,而是工程规范预留。以后如果你想再新建一个文件 config/_default/menus-extra.toml 追加菜单,只要那个文件顶部也写 _merge="deep",菜单就会追加,不会覆盖全部。
  3. 「必要配置」的含义:
    • hugo.toml:只放站点运行必要基础配置
    • menus.toml:只放菜单这一类必要配置
    • 不把所有配置全部堆在一个大文件里;不用的参数可以直接删掉,不要无脑复制主题全套默认配置

四、常见踩坑清单

  1. ❌ 剪切菜单的时候,漏剪了某个子菜单,菜单消失
  2. ❌ 剪切完 hugo.toml 还残留半截 [[menus.main]],Hugo 报解析错误
  3. ❌ identifier 重复,菜单渲染异常、随机消失
  4. ❌ parent 写错名字(大小写敏感!),子菜单不会挂载到父菜单,变成一级菜单
  5. ❌ 文件夹名字写错:_default 前后是下划线,不能写成 default

五、后续新增菜单怎么操作

直接在 menus.toml 文件末尾追加 [[menus.main]] 块即可,不用动 hugo.toml。

04-带注释的 menus.toml 模板还没有使用,使用的是将主题下关于菜单,单独抽离出来

05-将菜单单独抽离出来