Hugo 菜单遍历方法全解析:ByName、ByWeight、Limit、Reverse 实战指南
Hugo 菜单遍历方法全解析ByName、ByWeight、Limit、Reverse 实战指南【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoHugo 的Menu类型提供了一组用于遍历菜单条目menu entries的排序与截取方法。本文基于 Hugo 官方文档的 Menu methods 章节结合 navigation 包 的源码实现系统讲解ByName、ByWeight、Limit、Reverse四个方法的用途、排序规则、模板写法与源码原理读完即可在导航栏、页脚或面包屑等模板中熟练控制菜单条目的展示顺序与数量。方法与排序概览在 Hugo 中Menu是一个菜单条目的集合定义于 navigation/menu.go// Menu is a collection of menu entries. type Menu []*MenuEntry // Menus is a dictionary of menus. type Menus map[string]Menu每个MenuEntry包含标识符Identifier、名称Name、父级Parent、权重Weight、链接地址URL/PageRef、标题Title以及可选的Pre、Post前后缀 HTML 与自定义Params具体定义见 MenuConfig 结构体。四个方法的签名与作用如下方法签名作用返回类型ByNameMENU.ByName按条目name排序navigation.MenuByWeightMENU.ByWeight按weight、再按name、再按identifier排序默认排序navigation.MenuLimitMENU.Limit N仅返回前 N 个条目navigation.MenuReverseMENU.Reverse反转条目的当前排序顺序navigation.Menu这些方法不修改原始菜单而是返回一个新的有序或截取后的菜单副本因此可以在range中安全地链式调用例如.Site.Menus.main.ByName.Limit 2。ByName按名称排序ByName方法返回按name排序的菜单条目。考虑如下菜单定义# hugo.toml [[menus.main]] name Services pageRef /services weight 10 [[menus.main]] name About pageRef /about weight 20 [[menus.main]] name Contact pageRef /contact weight 30在模板中按name排序遍历ul {{ range .Site.Menus.main.ByName }} lia href{{ .URL }}{{ .Name }}/a/li {{ end }} /ulHugo 渲染结果为ul lia href/about/About/a/li lia href/contactContact/a/li lia href/services/Services/a/li /ul从源码看ByName的实现通过比较m1.Name与m2.Name来决定顺序使用compare.LessStrings见 navigation/menu.go// ByName sorts the menu by the name defined in the menu configuration. func (m Menu) ByName() Menu { const key menuSort.ByName title : func(m1, m2 *MenuEntry) bool { return compare.LessStrings(m1.Name, m2.Name) } menus, _ : smc.get(key, menuEntryBy(title).Sort, m) return menus }使用 sort 函数的替代方案你也可以使用sort函数 来排序菜单条目。例如按name降序排列ul {{ range sort .Site.Menus.main Name desc }} lia href{{ .URL }}{{ .Name }}/a/li {{ end }} /ul使用sort函数配合菜单条目时可以指定以下任一键Identifier、Name、Parent、Post、Pre、Title、URL或Weight。这些键对应 MenuConfig 中的字段名。ByWeight默认排序规则ByWeight方法返回按weight、再按name、再按identifier排序的菜单条目。这是 Hugo 菜单的默认排序顺序——即使不显式调用任何排序方法Hugo 也会按此规则渲染菜单。考虑如下带identifier的菜单定义# hugo.toml [[menus.main]] identifier about name About pageRef /about weight 20 [[menus.main]] identifier services name Services pageRef /services weight 10 [[menus.main]] identifier contact name Contact pageRef /contact weight 30在模板中按weight、name、identifier依次排序ul {{ range .Site.Menus.main.ByWeight }} lia href{{ .URL }}{{ .Name }}/a/li {{ end }} /ulHugo 渲染结果为ul lia href/services/Services/a/li lia href/about/About/a/li lia href/contactContact/a/li /ul[!NOTE] 在上面的菜单定义中identifier属性只有在两个或更多菜单条目具有相同name或需要使用翻译表本地化名称时才必须提供。源码中的默认排序比较器完整展现了先 weight、再 name、再 identifier的优先级见 navigation/menu.govar defaultMenuEntrySort func(m1, m2 *MenuEntry) bool { if m1.Weight m2.Weight { c : compare.Strings(m1.Name, m2.Name) if c 0 { return m1.Identifier m2.Identifier } return c 0 } if m2.Weight 0 { return true } if m1.Weight 0 { return false } return m1.Weight m2.Weight }一个容易忽略的细节是weight 为 0 的条目会被排到所有带 weight 的条目之后源码中m2.Weight 0返回true、m1.Weight 0返回false的两个分支保证了这一点。因此若希望某个条目固定在列表最前应给它赋一个正权重而不设置 weight 的条目默认按 weight0 处理、排在末尾。ByWeight方法本身通过缓存调用此默认排序器见 navigation/menu.go。使用 sort 函数的替代方案同样可以使用sort函数按weight降序排列ul {{ range sort .Site.Menus.main Weight desc }} lia href{{ .URL }}{{ .Name }}/a/li {{ end }} /ul可指定的键与ByName一节相同Identifier、Name、Parent、Post、Pre、Title、URL或Weight。Limit截取前 N 个条目Limit方法返回给定的菜单仅保留前 N 个条目。它常与排序方法链式使用——先排序、再截取以得到权重最高的前 N 项之类的效果。仍以上一节的菜单定义Services/About/Contact为例先按名称排序、再只取前 2 项ul {{ range .Site.Menus.main.ByName.Limit 2 }} lia href{{ .URL }}{{ .Name }}/a/li {{ end }} /ulHugo 渲染结果为ul lia href/about/About/a/li lia href/contactContact/a/li /ul源码实现非常直接见 navigation/menu.go// Limit limits the returned menu to n entries. func (m Menu) Limit(n int) Menu { if len(m) n { return m[0:n] } return m }当菜单条目数不超过 N 时Limit原样返回整个菜单不会报错也不会补空当条目数超过 N 时通过切片m[0:n]截取前 N 项。实际项目中可用它实现只显示最新/最靠前的 5 个导航链接等场景。Reverse反转排序顺序Reverse方法返回反转排序顺序后的菜单通常与ByName、ByWeight等排序方法链式调用以获得降序效果。以同名菜单定义为例先按名称升序、再反转即得到按名称降序的结果ul {{ range .Site.Menus.main.ByName.Reverse }} lia href{{ .URL }}{{ .Name }}/a/li {{ end }} /ulHugo 渲染结果为ul lia href/services/Services/a/li lia href/contactContact/a/li lia href/about/About/a/li /ul源码实现采用经典的双指针原地交换见 navigation/menu.go// Reverse reverses the order of the menu entries. func (m Menu) Reverse() Menu { const key menuSort.Reverse reverseFunc : func(menu Menu) { for i, j : 0, len(menu)-1; i j; i, j i1, j-1 { menu[i], menu[j] menu[j], menu[i] } } menus, _ : smc.get(key, reverseFunc, m) return menus }Reverse是对当前顺序的整体反转而非按某个字段降序排序。因此它的语义取决于前置排序ByName.Reverse是名称降序ByWeight.Reverse则是 weight 降序。若菜单尚未排序Reverse反转的就是配置中的原始声明顺序。链式调用与缓存机制四个方法均可任意组合形成排序 → 截取 → 反转的链式调用例如!-- 按 weight 升序取前 3 项后再反转实际得到 weight 较大的前 3 项 -- ul {{ range .Site.Menus.main.ByWeight.Limit 3.Reverse }} lia href{{ .URL }}{{ .Name }}/a/li {{ end }} /ul从源码可以观察到ByName、ByWeight、Reverse三个方法都通过smc.get(key, ...)获取结果smc是一个包级共享的菜单缓存实例var smc newMenuCache()见 navigation/menu.go。缓存实现在 navigation/menu_cache.go 中它以方法名如menuSort.ByName为键、以传入的原始菜单列表为匹配条件命中时直接返回已排序的结果未命中时才执行排序并写入缓存。这意味着在同一个页面构建周期内多次调用ByName/ByWeight/Reverse不会重复排序对大型站点的高频导航渲染是重要的性能保障。小结ByWeight是 Hugo 菜单的默认排序先weight再name最后identifierweight 为 0 的条目排末尾。ByName忽略 weight仅按名称排序需要降序时配合Reverse或sort函数。Limit N截取前 N 项常与排序方法链式使用Reverse整体反转当前顺序。使用sort函数时可指定的排序键为Identifier、Name、Parent、Post、Pre、Title、URL、Weight。四个方法的实现与默认排序器均位于 navigation/menu.go排序结果缓存逻辑见 navigation/menu_cache.go相关行为可参考 navigation 包测试。掌握这四个方法即可在 Hugo 模板中精确控制导航菜单的显示顺序与数量无需引入任何额外依赖或自定义排序逻辑。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

容灾备份核心指南:RPO/RTO、架构选型与演练落地

容灾备份核心指南:RPO/RTO、架构选型与演练落地

简介:容灾备份通用基础知识培训PPT课件面向IT运维、数据中心管理人员及企业业务连续性负责人,系统讲解灾备的定义、作用、衡量标准(RTO与RPO)以及实现方法,帮助初学者快速建立灾备知识框架。课件内容涵盖数据中心面临的…

2026/9/20 19:00:02 阅读更多 →
六个盒子组织诊断:从静态打分到动态脉动探查

六个盒子组织诊断:从静态打分到动态脉动探查

简介:本资源是一份面向HR从业者、组织发展顾问及企业管理者的专业PPT课件,系统讲解韦斯伯德提出的六个盒子模型——这一诞生于20世纪70年代、被阿里云与波音等企业实践验证的组织诊断经典工具。课件完整覆盖六大核心维度:目的、结构、关系、激…

2026/9/19 16:37:27 阅读更多 →
CANoe工程中SOME/IP报文拆解与Endpoint配置实战

CANoe工程中SOME/IP报文拆解与Endpoint配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 16:37:27 阅读更多 →

最新新闻

pandoc 的 opendocument 交叉引用扩展(xrefs_name / xrefs_number)源码级解析

pandoc 的 opendocument 交叉引用扩展(xrefs_name / xrefs_number)源码级解析

pandoc 的 opendocument 交叉引用扩展(xrefs_name / xrefs_number)源码级解析 【免费下载链接】pandoc Universal markup converter 项目地址: https://gitcode.com/gh_mirrors/pa/pandoc 本篇文章基于 pandoc 官方命令行测试 test/command/6774.…

2026/9/20 19:57:43 阅读更多 →
具身智能开发入门:从感知决策到边缘部署

具身智能开发入门:从感知决策到边缘部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 19:57:43 阅读更多 →
dbx 仓库内 rumqttc 事件循环流式设计深度解析:面向弱网环境的 MQTT 客户端架构

dbx 仓库内 rumqttc 事件循环流式设计深度解析:面向弱网环境的 MQTT 客户端架构

dbx 仓库内 rumqttc 事件循环流式设计深度解析:面向弱网环境的 MQTT 客户端架构 【免费下载链接】dbx 15MB,轻量级跨平台数据库客户端、数据库管理工具。支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server 等。15MB, lig…

2026/9/20 19:57:43 阅读更多 →
ML-Agents 学习环境设计指南:从场景搭建到训练闭环的完整实践

ML-Agents 学习环境设计指南:从场景搭建到训练闭环的完整实践

ML-Agents 学习环境设计指南:从场景搭建到训练闭环的完整实践 【免费下载链接】ml-agents The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intellig…

2026/9/20 19:57:43 阅读更多 →
@visx/grid 网格线组件完全指南:为 visx 图表添加横向、纵向与极坐标网格

@visx/grid 网格线组件完全指南:为 visx 图表添加横向、纵向与极坐标网格

visx/grid 网格线组件完全指南:为 visx 图表添加横向、纵向与极坐标网格 【免费下载链接】visx 🐯 visx | visualization components 项目地址: https://gitcode.com/gh_mirrors/vi/visx visx/grid 是 visx 可视化组件库中专用于绘制图表网格线的…

2026/9/20 19:57:43 阅读更多 →
ADB自适应远光电子系统架构:感知、决策与执行全链路设计

ADB自适应远光电子系统架构:感知、决策与执行全链路设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 19:56:43 阅读更多 →

日新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →