- 开发工具
- 前端
- CLI
【免费下载链接】hugo
The world’s fastest framework for building websites.
导读
在 Hugo 中,一个页面可以按多种输出格式(如html、rss、json)渲染,而"主输出格式"(primary output format)决定了页面在多种格式并存时的"默认身份"——它直接控制Permalink、RelPermalink等方法的返回值,并影响站点链接与规范 URL 的生成。本文将基于 Hugo 源码与官方配置文档,完整讲解主输出格式的定义、配置方式、排序规则及其在源码中的实现原理,帮助你准确掌控多输出格式站点的链接行为。
一、什么是主输出格式
根据官方术语表,主输出格式是:对于给定的页面种类(page kind),其在 outputs 配置数组中的第一个条目。
定义虽然只有一句话,但含义深远。outputs配置为每种页面种类声明了一组待渲染的输出格式,例如home页面的默认配置通常形如['html', 'rss', 'json']。数组中元素的先后顺序是语义化的:排在第一位的html就是该页面种类的主输出格式,后续的rss、json则是它的"备选"输出格式(alternative output formats)。
主输出格式是构建期间由 Hugo 引擎自动推导的,你无法单独指定"谁是主输出格式",只能通过调整outputs数组的顺序或修改输出格式的weight属性来间接影响它。
二、主输出格式在源码中的实现
从源码结构看,主输出格式的推导发生在页面路径(target path)的构建阶段。在 hugolib/page__paths.go 中,页面为每种输出格式逐一生成pageOutputFormats数组后,直接取数组首元素作为主输出格式:
// Use the main format for permalinks, usually HTML. permalinksIndex := 0 if f.Permalinkable { // Unless it's permalinkable. permalinksIndex = i }随后在构建pagePaths结构时,将数组第一个元素登记为firstOutputFormat:
return pagePaths{ outputFormats: out, firstOutputFormat: pageOutputFormats[0], // 主输出格式 = 数组第一个条目 targetPaths: targets, targetPathDescriptor: targetPathDescriptor, }, nil这段代码印证了术语定义:主输出格式就是输出格式数组的第一个条目,源码通过pageOutputFormats[0]直接取用。
那么数组的"第一个条目"是如何确定的?这取决于输出格式的排序。在 hugolib/site.go 中,站点按页面种类收集输出格式后执行排序:
// Add the per kind configured output formats for _, kind := range kinds.AllKindsInPages { if siteFormats, found := s.conf.C.KindOutputFormats[kind]; found { for _, f := range siteFormats { if !formatSet[f.Name] { formats = append(formats, f) formatSet[f.Name] = true } } } } sort.Sort(formats) s.renderFormats = formats因此,主输出格式的最终确定流程可以概括为:outputs配置(或页面 front matter 的outputs字段)声明格式集合 → 按weight与名称排序 → 排序后的数组首元素即为主输出格式。
三、outputs 配置:主输出格式的声明入口
主输出格式的声明源头是 outputs 配置文档所描述的outputs参数。Hugo 为每种页面种类提供了默认输出格式配置,你可以在项目的hugo.toml/hugo.yaml/hugo.json中按页面种类覆盖。
例如,为home页面种类额外渲染内置的json输出格式(前提是你已创建了对应模板):
[outputs] home = ['html','rss','json']注意此示例只声明了home这一种页面种类——你无需为其他页面种类补充条目,除非你想修改它们的默认输出格式。
官方配置文档特别强调了一个关键点:
数组中的顺序很重要。第一个元素将是该页面种类的主输出格式,在大多数情况下应为默认配置所示的
html。
也就是说,如果你把home配置为['json', 'html', 'rss'],那么json将成为该页面种类的主输出格式,进而影响该页面种类下所有页面的Permalink行为。
页面级别的覆盖
除站点级配置外,还可以在单个页面的 front matter 中通过outputs字段追加输出格式,例如content/example.md:
title = 'Example' outputs = ['json']在默认配置下,Hugo 会为该页面同时渲染html和json两种输出格式。front matter 中的outputs字段是追加而非替换项目级配置——站点级outputs数组的顺序仍然决定主输出格式。
四、weight 排序:间接改变主输出格式
除了直接调整outputs数组顺序,你还可以通过修改输出格式的weight属性来影响排序结果。根据 output-formats 配置文档 的说明:
weight: (int)设为非零值时,Hugo 以weight作为排序的第一标准,仅在weight相同时回退到按输出格式名称排序。数值越小越靠前,越大越靠后。Hugo 按此排序顺序依次渲染输出格式。默认值为0,唯一例外是html输出格式,其默认weight为10。
例如,想让json在同时生成时优先于html渲染(从而成为主输出格式):
[outputFormats.json] weight = 1 [outputFormats.html] weight = 2这里只需声明与默认值不同的属性即可。需要强调的是:weight的作用域是输出格式本身,而主输出格式的判定依据是排序后数组的第一个条目,因此调整weight是改变主输出格式的间接手段。
五、主输出格式如何影响 Permalink 与 RelPermalink
主输出格式最直接的实战影响,体现在Page对象的Permalink与RelPermalink方法上。
根据 output-formats 配置文档 与 outputs 配置文档 的说明,规则如下:
- 对于
permalinkable设置为true的输出格式(如内置的html和amp),这两个方法返回该输出格式自身的 URL,与其在数组中的位置无关; - 对于所有其他输出格式,这两个方法返回页面主输出格式的 URL。
举例说明。在page.json.json模板(即以json输出格式渲染的页面模板)中,如果json不是主输出格式,你会看到:
{{ .RelPermalink }} → /that-page/ {{ with .OutputFormats.Get "json" }} {{ .RelPermalink }} → /that-page/index.json {{ end }}页面自身的RelPermalink指向主输出格式(html)的/that-page/,只有显式通过.OutputFormats.Get "json"才能拿到json的地址。
如果将json输出格式的permalinkable设为true,那么在同一个page.json.json模板中行为反转:
{{ .RelPermalink }} → /that-page/index.json {{ with .OutputFormats.Get "html" }} {{ .RelPermalink }} → /that-page/ {{ end }}这一设计使主输出格式成为多格式站点中"默认链接"的锚点:无论当前渲染的是哪种格式,未显式指定格式的链接都会指向主输出格式,确保站点内链接的稳定与一致。
源码佐证:permalinksIndex 的选择
前文引用的 hugolib/page__paths.go 正是这一行为的底层实现:
// Use the main format for permalinks, usually HTML. permalinksIndex := 0 if f.Permalinkable { // Unless it's permalinkable. permalinksIndex = i } targets[f.Name] = targetPathsHolder{ relURL: relPermalink, paths: paths, OutputFormat: pageOutputFormats[permalinksIndex], }默认情况下permalinksIndex指向0,即主输出格式(通常是 HTML);只有当前格式Permalinkable为真时,才改用当前格式自身的路径。这与官方文档的描述完全一致,也从源码层面证实了"主输出格式决定默认 Permalink"这一结论。
六、主输出格式与其他机制的关系
与备选输出格式(AlternativeOutputFormats)
主输出格式与AlternativeOutputFormats方法返回的备选格式集合互补:备选集合是除当前格式以外的所有输出格式。典型用法是在<head>中为搜索引擎输出格式切换链接:
{{ range .AlternativeOutputFormats }} <link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}"> {{ end }}与规范输出格式(canonical output format)
output-formats 配置文档 还引入了rel属性:Hugo 用它判断当前页面的规范输出格式。内置html输出格式的rel默认值为canonical,其余内置格式默认为alternate。主输出格式决定了默认 URL 的归属,而rel属性则决定了哪个格式被视为规范版本,二者共同构成多输出格式站点的链接语义体系。
与模板查找顺序
每个输出格式都需要符合模板查找顺序的模板。对于最高特异性,模板文件名可采用[页面种类].[输出格式].[后缀]的形式,例如:
| 输出格式 | 模板路径 |
|---|---|
html | layouts/section.html.html |
json | layouts/section.json.json |
rss | layouts/section.rss.xml |
主输出格式本身不要求特殊模板——它是排序的结果而非模板命名规则,但了解模板查找顺序有助于确认每种格式都被正确渲染,从而保证outputs数组中的首元素(即主输出格式)确实有对应的模板可执行。
七、小结与最佳实践
| 关键结论 | 说明 |
|---|---|
| 定义 | 主输出格式 = 某页面种类在outputs配置数组中的第一个条目 |
| 声明方式 | 通过站点级[outputs]配置或页面 front matter 的outputs字段 |
| 间接调整 | 修改输出格式的weight(html默认为10)可改变排序,进而改变主输出格式 |
| 核心影响 | 决定Permalink/RelPermalink的默认返回值;permalinkable格式返回自身 URL |
| 源码位置 | hugolib/page__paths.go 取pageOutputFormats[0],hugolib/site.go 完成格式排序 |
实践中的两条经验:
- 主输出格式通常保持为
html:默认配置正是如此,这保证站内链接、规范 URL 与别名重定向等行为符合常规预期; - 需要 JSON/XML 时不要打乱首位顺序:如需为某页面种类增加
json,写成['html', 'rss', 'json']而非把json放到最前,除非你确实想改变该页面种类的主输出格式及其链接语义。
如需进一步深入,可继续阅读 outputs 配置、output-formats 配置 以及术语表中的 output format 条目,并结合 hugolib/page__paths.go 源码验证本文所述行为。
- 开发工具
- 前端
- CLI
【免费下载链接】hugo
The world’s fastest framework for building websites.
相关推荐
Hugo 深入解析:canonical output format(规范化输出格式)的判定规则与模板用法
Hugo 深入解析:canonical output format(规范化输出格式)的判定规则与模板用法 canonical output format 是 H
开发工具前端CLIHugo 输出格式(Output Formats)完整配置指南:从默认行为到自定义 Atom 源
Hugo 输出格式(Output Formats)完整配置指南:从默认行为到自定义 Atom 源 输出格式(output format)是 Hugo 将页面渲染
开发工具前端CLI5 分钟解除 PDF 复制打印限制:PDFPatcher 免费权限去除工具一次搞定
5 分钟解除 PDF 复制打印限制:PDFPatcher 免费权限去除工具一次搞定 PDFPatcher(PDF补丁丁)是一款免费、开源、免安装的 PDF 权限
桌面应用文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考