Hugo 菜单条目 Identifier 方法:从属性取值到多语言本地化的完整实战
【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo
本篇技术指南聚焦 Hugo 中菜单条目(MenuEntry)的Identifier方法:它返回菜单条目的identifier属性,在自动生成的菜单中则返回页面所属的 section。你将掌握identifier在项目配置与 front matter 中的定义方式、结合翻译表(T)实现多语言菜单名的经典写法,以及该方法在 Hugo 源码(navigation/menu.go)中如何参与条目排序与重复检测,从而写出更健壮、可本地化的菜单模板。
方法签名与返回值
Identifier是MenuEntry类型上的一个方法,其签名与返回类型如下:
| 项目 | 说明 |
|---|---|
| 方法名 | Identifier |
| 签名 | MENUENTRY.Identifier |
| 返回类型 | string |
调用方式为在模板中直接对菜单条目取值:
{{ .Identifier }}其中.是range迭代到当前MenuEntry时的上下文。Identifier返回该菜单条目的identifier属性值;如果菜单条目是通过 Hugo 的“自动定义”机制(sectionPagesMenu)生成的,则返回的是该条目对应页面的 section 名称(详见下文“自动定义”一节)。
三种定义方式与 identifier 的取值来源
Hugo 提供三种定义菜单条目的方式,identifier属性在不同方式下的行为不同:
- 项目配置中定义:显式(或省略)设置
identifier属性; - 页面 front matter 中定义:同样通过
menus键配置; - 自动定义:
identifier由 Hugo 自动赋值为顶级 section 的名称。
在项目配置中定义
在hugo.toml/hugo.yaml/hugo.json中定义[[menus.main]]条目时,可以显式指定identifier:
[[menus.main]] identifier = 'about' name = 'About' pageRef = '/about' weight = 10 [[menus.main]] identifier = 'contact' name = 'Contact' pageRef = '/contact' weight = 20配置解析发生在 navigation/menu.go 的DecodeConfig中:每个菜单条目通过mapstructure.WeakDecode解码为MenuConfig结构体,其中就包含Identifier string字段(见 navigation/menu.go),随后包装成MenuEntry并加入对应的菜单集合。
在 front matter 中定义
在页面 front matter 中也可以为菜单条目设置identifier:
title = 'About' [menus.main] identifier = 'about' weight = 10关于 front matter 中可用的菜单条目属性,可参考 content-management/menus.md。
自动定义:返回页面 section
当在项目配置中启用sectionPagesMenu时,Hugo 会为站点的每个顶级 section 自动创建一个菜单条目:
sectionPagesMenu = 'main'在源码 hugolib/site.go 中可以看到,自动生成的条目会这样构造:
me := navigation.MenuEntry{ Identifier: id, // id 即 p.Section(),若为空则为 "/" Name: p.LinkTitle(), Weight: p.Weight(), Page: p, }也就是说,这类条目的Identifier方法返回值就是页面的 section。相关行为由TestMenusSectionPagesMenu(见 hugolib/menu_test.go)等测试用例覆盖验证。
实战:结合翻译表实现多语言菜单名
Identifier最常见的实战用途,是在多语言站点中作为翻译表(i18n)的查询键。T(即i18n)函数接收Identifier的返回值去查翻译表,若存在匹配键则使用翻译后的名称,否则回退到name属性:
<ul> {{ range .Site.Menus.main }} <li><a href="{{ .URL }}">{{ or (T .Identifier) .Name }}</a></li> {{ end }} </ul>这一写法在 Hugo 官方菜单模板文档中也有体现(见 templates/menu.md):遍历菜单条目时,先尝试用.Identifier通过T获取本地化名称,取不到再回退.Name。对于支持多语言的递归菜单 partial 模板,可以按同样的模式处理每一层条目及其子条目。
源码视角:Identifier 在条目识别中的底层作用
除了模板取值,identifier在 Hugo 内部还承担着条目身份识别的作用,理解这一点有助于规避重复定义问题。
在 navigation/menu.go 中,KeyName()方法优先返回Identifier,为空时才回退到Name:
func (m *MenuEntry) KeyName() string { if m.Identifier != "" { return m.Identifier } return m.Name }KeyName()被用于 hugolib/site.go 中的扁平哈希键(twoD{菜单名, KeyName()}),从而在合并配置条目、自动条目与 front matter 条目时检测“重复的菜单条目”(源码中会报错duplicate menu entry with identifier ...)。可以推断,当identifier缺失时,Name便充当了去重键,这也解释了为什么以下场景必须显式设置identifier。
identifier还参与菜单排序:在defaultMenuEntrySort(见 navigation/menu.go)中,当两个条目的weight与name都相同时,会进一步用Identifier做字符串比较决定先后顺序。
注意事项
[!NOTE] 在上述菜单定义中,
identifier属性仅在以下两种情况必需:
- 两个或更多菜单条目具有相同的
name;- 需要借助翻译表对菜单名进行本地化(如上面的
T .Identifier用法)。其他场景可以省略
identifier,Hugo 会自动回退使用name(如KeyName()所示)。
小结
MenuEntry.Identifier返回string,即菜单条目的identifier属性;自动定义的条目返回页面 section;identifier可在项目配置或 front matter 中显式定义,语义清晰、稳定,建议在多语言站点中始终设置;- 结合
T函数,Identifier是菜单本地化的核心键;结合源码可知它还参与条目去重与排序; - 相关实现可深入阅读 navigation/menu.go 与 hugolib/site.go,菜单整体定义与模板渲染见 content-management/menus.md 与 templates/menu.md。
【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考