# 全部菜单迁移到独立



>核心目标：
>
>1. `hugo.toml`（根目录）不再放任何 `menus` 菜单代码，只保留站点基础配置、主题参数
>2. 所有导航菜单统一放在 `config/_default/menus.toml` 单独维护
>3. 理解：**这个场景下，`_merge = "deep"` 可加，但它的作用是为以后再拆分追加配置留后路**（文档 “合并必要配置” 的思想：按需拆分、按需合并，不写冗余配置）
>4. 风险消失：不会出现多文件菜单互相覆盖

## 一、目录结构对照（最终状态）

```
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 模板（直接替换使用）

```
# ==============================================
# _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-将菜单单独抽离出来

---

> 作者: Anonymous  
> URL: https://www.1mt.run/posts/583bc6b/  

