- 开发工具
- 前端
- CLI
【免费下载链接】hugo
The world’s fastest framework for building websites.
本指南围绕 Hugo 中获取“全维度站点集合”的Sites方法展开,涵盖其返回值类型、三级排序规则、在 multilingual + multiversion 项目中的实战用法,以及 v0.156.0 起的弃用迁移路径。读完本文,你将能正确使用hugo.Sites/hugo.Sites.Default遍历语言、版本、角色三个维度上的全部站点,并理解其底层实现机制。
一、Sites 方法是什么
Sites是 Hugo 站点对象(Site)提供的一个方法,用于返回所有维度(language、version、role)上的全部站点集合。在模板中通过SITE.Sites调用,返回类型为page.Sites(见 Sites.md 的 front matter 定义:returnType: page.Sites、signatures: [SITE.Sites])。
在单个站点(site)的模板上下文里,Sites集合让开发者能够从当前语言/版本的视角,一次性访问整个站点矩阵——包括其他语言、其他版本、其他角色的站点。
注意:
Sites是无参方法,直接{{ .Sites }}即可得到集合对象,通常配合range遍历使用。
二、重要变更:v0.156.0 起已弃用
该文档明确标注了弃用状态(deprecated 2026-02-18 in v0.156.0):
Use the
hugo.Sitesfunction instead.
即从 v0.156.0 开始,模板中应改用全局函数hugo.Sites替代Site.Sites/Page.Sites。新函数对应的完整文档位于 hugo/Sites.md,标注为new-in 0.156.0。
迁移对应关系:
| 旧写法(已弃用) | 新写法(推荐) |
|---|---|
{{ .Site.Sites }} | {{ hugo.Sites }} |
{{ .Sites }}(页面上下文) | {{ hugo.Sites }} |
从源码看,旧方法仍保留兼容但会触发弃用告警。在 hugolib/site.go 中:
// Returns all sites for all dimensions. // Deprecated: Use hugo.Sites instead. func (s *Site) Sites() page.Sites { s.h.printSiteSitesDeprecationInit.Do(func() { hugo.Deprecate(".Site.Sites and .Page.Sites", "Use hugo.Sites instead.", "v0.156.0") }) return slices.Collect(s.h.allSitesInterface(nil)) }可以看到它通过printSiteSitesDeprecationInit只输出一次弃用提示,随后仍委托给底层的allSitesInterface完成实际遍历,因此功能语义与hugo.Sites完全一致,区别仅在告警与调用入口。
三、返回集合的排序规则
Sites返回的集合遵循层级排序(hierarchical sort):每个后续维度作为前一维度的 tie-breaker。该规则定义在共享文档 sites-collection.md 中,具体如下:
- Language(语言):按
weight升序排序;若weight相同或未定义,回退到字典序(lexicographical order)。 - Version(版本):在语言排序之后,按
weight升序;若并列,Hugo 默认采用语义版本降序(descending semantic sort)。 - Role(角色):最后按
weight升序排序,最终回退到字典序。
也就是说,集合顺序 = 先按语言排,再按版本排,最后按角色排。理解这一顺序对依赖遍历顺序输出导航、语言切换器或版本选择器至关重要。
四、实战配置:多语言 + 多版本项目
以 hugo/Sites.md 中的完整配置为例,一个包含两种语言(de、en)和三个版本(v1.0.0、v2.0.0、v3.0.0)的项目配置如下:
defaultContentLanguage = 'en' defaultContentLanguageInSubdir = true defaultContentVersionInSubdir = true [languages.de] contentDir = 'content/de' direction = 'ltr' label = 'Deutsch' locale = 'de-DE' title = 'Projekt Dokumentation' weight = 1 [languages.en] contentDir = 'content/en' direction = 'ltr' label = 'English' locale = 'en-US' title = 'Project Documentation' weight = 2 [versions.'v1.0.0'] [versions.'v2.0.0'] [versions.'v3.0.0']关键参数说明:
defaultContentLanguage = 'en':声明默认语言,决定hugo.Sites.Default落在哪个语言上(对应配置文档中的defaultContentLanguage项);defaultContentLanguageInSubdir = true:默认语言内容也放在子目录(URL 中体现为/en/前缀);defaultContentVersionInSubdir = true:默认版本内容也放在子目录(URL 中体现为/v3.0.0/前缀);- 每个
[languages.xx]块定义一种语言:contentDir指定内容目录、weight控制排序权重、title/label/locale用于展示与本地化; - 每个
[versions.'x.y.z']块声明一个版本维度;未显式配置 weight 时,版本并列,Hugo 按语义版本降序排列(即 v3.0.0 排最前)。
五、模板用法与输出示例
1. 遍历全部站点
下面的模板(来自官方文档示例)遍历所有站点,为每个站点的首页生成链接,同时显示站点标题和版本名:
<ul> {{ range hugo.Sites }} <li><a href="{{ .Home.RelPermalink }}">{{ .Title }} {{ .Version.Name }}</a></li> {{ end }} </ul>配合上文配置,输出结果为(注意顺序符合排序规则:德语 weight 更小故排前,版本按语义降序 v3.0.0 → v1.0.0):
<ul> <li><a href="/v3.0.0/de/">Projekt Dokumentation v3.0.0</a></li> <li><a href="/v2.0.0/de/">Projekt Dokumentation v2.0.0</a></li> <li><a href="/v1.0.0/de/">Projekt Dokumentation v1.0.0</a></li> <li><a href="/v3.0.0/en/">Project Documentation v3.0.0</a></li> <li><a href="/v2.0.0/en/">Project Documentation v2.0.0</a></li> <li><a href="/v1.0.0/en/">Project Documentation v1.0.0</a></li> </ul>2. 定位默认站点
hugo.Sites.Default返回默认站点——即默认语言(defaultContentLanguage)、默认版本、默认角色交汇处的站点,与其在集合中的位置无关:
{{ with hugo.Sites.Default }} <a href="{{ .Home.RelPermalink }}">{{ .Title }}</a> {{ end }}对于上文配置,该模板渲染出英文 v3.0.0 站点的首页链接。尽管三个德语站点因weight更小排在最前,但defaultContentLanguage = 'en'决定了默认站点是英文站点。注意Default需要用with包裹以处理空值场景。
3. 旧 API 写法(v0.156.0 前)
在升级前,等价的旧写法是{{ range .Site.Sites }}/{{ .Site.Sites.Default }}。由于新函数与旧方法共享底层实现,迁移时只需机械替换调用入口即可,输出结果完全一致。
六、源码实现解析
1. 全局函数入口
hugo.Sites由hugoSitesSitesProvider提供,定义于 hugolib/hugo_sites.go:
// hugoSitesSitesProvider is a wrapper that implements page.SitesProvider. // This avoids naming conflict with HugoSites.Sites field. type hugoSitesSitesProvider struct { h *HugoSites } func (sp hugoSitesSitesProvider) Sites() page.Sites { return slices.Collect(sp.h.allSitesInterface(nil)) }注释点明了设计动机:该包装类型实现了page.SitesProvider接口,避免与HugoSites.Sites字段命名冲突。
2. 核心遍历逻辑
新旧两种入口最终都汇聚到allSitesInterface(hugolib/hugo_sites.go):
func (h *HugoSites) allSitesInterface(include func(s page.Site) bool) iter.Seq[page.Site] { if include == nil { include = func(s page.Site) bool { return true } } return func(yield func(s page.Site) bool) { for _, v := range h.sitesVersionsRoles { for _, r := range v { for _, s := range r { if !include(s) { continue } // Site() returns a wrapped version of the site that only exposes the page.Site interface. if !yield(s.Site()) { return } } } } } }从该实现可以推断出:
- 站点的组织结构是嵌套的
sitesVersionsRoles(语言 → 版本 → 角色)三维矩阵,allSitesInterface以三重循环展开它,这与文档中“所有维度(language/version/role)”的描述一一对应; - 返回给模板的每个元素通过
s.Site()包装,只暴露page.Site接口,保证模板层无法触碰内部实现; - 函数签名支持传入
include过滤函数,为内部按维度筛选站点预留了能力(传入nil时返回全部站点)。
3. 站点包装层
resources/page包中,siteWrapper.Sites()(resources/page/site.go)直接透传给内部站点对象:
func (s *siteWrapper) Sites() Sites { return s.s.Sites() }而page层面(如 resources/page/page.go 的nopHugoSitesProvider)也实现了同名方法,说明Sites是page.Site接口体系中的标准成员。
七、相关 API 与使用建议
Site.IsDefault:判断当前站点是否为全维度默认站点(源码位于 hugolib/site.go,即“Returns whether this site is the default across all dimensions”),常与Sites搭配实现“仅在默认站点输出”的逻辑;Site.Home:获取站点首页页面对象,Sites遍历中常用.Home.RelPermalink生成链接;Site.Version:获取站点所属版本信息,多版本站点中用于展示版本名;Site.Language:获取语言信息,多语言切换器中常与Sites联用。
升级建议:若你的模板仍在使用{{ .Site.Sites }}或{{ .Sites }},请尽快迁移到hugo.Sites(v0.156.0+),以避免弃用告警并在未来版本中保持兼容;多语言、多版本站点矩阵的排序、默认站点判定规则在新旧 API 间完全一致,可直接替换无需调整业务逻辑。
- 开发工具
- 前端
- CLI
【免费下载链接】hugo
The world’s fastest framework for building websites.
相关推荐
Hugo hugo.Sites 集合:Language / Version / Role 三维排序规则与默认站点详解
Hugo hugo.Sites 集合:Language / Version / Role 三维排序规则与默认站点详解 导读 本文围绕 Hugo 模板函数 hug
开发工具前端CLIHugo hugo.Sites 函数详解:跨语言、版本与角色维度的站点集合访问
Hugo hugo.Sites 函数详解:跨语言、版本与角色维度的站点集合访问 Hugo 0.156.0 引入了 hugo.Sites 模板函数,用于在构建多语
开发工具前端CLIHugo 多语言站点中的 Pages.ByLanguage 方法:按语言权重排序页面集合的完整指南
Hugo 多语言站点中的 Pages.ByLanguage 方法:按语言权重排序页面集合的完整指南 导读 ByLanguage 是 Hugo 中作用于 Page
开发工具前端CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考