本文档如何正确配置站点的媒体类型和输出格式, 以及为定制输出创建模板的路径

媒体类型

媒体类型 (也称为 MIME type 以及 内容类型content type) 是两部分组成的文件格式标志符, 也是网络上传输的内容格式。

这是Hugo内置的媒体类型的全部集合:

typesuffixes
application/javascript[js]
application/json[json]
application/octet-stream[]
application/rss+xml[xml]
application/toml[toml]
application/typescript[ts]
application/xml[xml]
application/yaml[yaml yml]
image/jpeg[jpg jpeg]
image/png[png]
image/svg+xml[svg]
text/calendar[ics]
text/css[css]
text/csv[csv]
text/html[html]
text/jsx[jsx]
text/plain[txt]
text/tsx[tsx]
text/x-sass[sass]
text/x-scss[scss]
video/3gpp[3gpp 3gp]
video/mp4[mp4]
video/mpeg[mpg mpeg]
video/ogg[ogv]
video/webm[webm]
video/x-msvideo[avi]

注意:

  • 可以添加定制媒体类型或者改变默认的媒体类型;比如,可以改变 text/html 的后缀为asp.
  • 后缀值会用于Hugo中对应的媒体类型的URLs和文件名称.
  • Type 是定义新的或者定制 Output Formats (见下面)必须使用的标志符.
  • 媒体类型的全部集合在Hugo的内置开发服务器中注册,以确保可以被浏览器识别

添加或者修改一个媒体类型,请在site configurationmediaTypes 部分添加或修改, 针对所有站点或者某给定语言.

config.
     
1
2
3
4
5
6
7
mediaTypes:
  text/enriched:
    suffixes:
    - enr
  text/html:
    suffixes:
    - asp
1
2
3
4
5
[mediaTypes]
  [mediaTypes."text/enriched"]
    suffixes = ["enr"]
  [mediaTypes."text/html"]
    suffixes = ["asp"]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
   "mediaTypes": {
      "text/enriched": {
         "suffixes": [
            "enr"
         ]
      },
      "text/html": {
         "suffixes": [
            "asp"
         ]
      }
   }
}

上面例子添加了一个媒体类型,text/enriched, 同时改变了内置 text/html 媒体类型的后缀.

注意: 这些媒体类型是为 您的输出格式 而配置的. 如果想重新定义Hugo的默认的输出格式中一个(比如HTML), 您也需要定义媒体类型。 下面配置改变了 HTML 输出格式从 默认的html 修改为 htm:

1
2
3
4
5
6
7
8
[mediaTypes]
[mediaTypes."text/html"]
suffixes = ["htm"]

# Redefine HTML to update its media type.
[outputFormats]
[outputFormats.HTML]
mediaType = "text/html"

注意 为上面代码工作, 您站点配置文件中需要一个outputs 定义.

输出格式定义 Output Format Definitions

给定一个媒体类型,添加一些配置,您就配置好了输出格式

这里是Hugo内置的输出格式的全部集合:

namemediaTypepathbaseNamerelprotocolisPlainTextisHTMLnoUglypermalinkable
HTMLtext/htmlindexcanonicalfalsetruefalsetrue
AMPtext/htmlampindexamphtmlfalsetruefalsetrue
CSStext/cssstylesstylesheettruefalsefalsefalse
CSVtext/csvindexalternatetruefalsefalsefalse
Calendartext/calendarindexalternatewebcal://truefalsefalsefalse
JSONapplication/jsonindexalternatetruefalsefalsefalse
ROBOTStext/plainrobotsalternatetruefalsefalsefalse
RSSapplication/rss+xmlindexalternatefalsefalsetruefalse
Sitemapapplication/xmlsitemapsitemapfalsefalsetruefalse
  • 每个页面能够以您需要的任意多输出格式输出, 而且您可以定义任意数量的输出格式, 只要他们解析到文件系统的唯一路径.上表中,最佳的例子是AMPHTML 对比。AMP路径amp, 所以它不覆盖HTML版本, 进而我们可以访问 /index.html/amp/index.html.
  • MediaType必须和已经定义的某个媒体类型的Type匹配
  • 可以定义新的输出格式,或者重定义内置的输出格式,比如想将AMP页面置于不同路径.

添加或者修改一个输出类型,请在site configurationoutputFormats 部分添加或修改, 针对所有站点或者某给定语言.

config.
     
1
2
3
4
5
6
outputFormats:
  MyEnrichedFormat:
    baseName: myindex
    isPlainText: true
    mediaType: text/enriched
    protocol: bep://
1
2
3
4
5
6
[outputFormats]
  [outputFormats.MyEnrichedFormat]
    baseName = "myindex"
    isPlainText = true
    mediaType = "text/enriched"
    protocol = "bep://"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
   "outputFormats": {
      "MyEnrichedFormat": {
         "baseName": "myindex",
         "isPlainText": true,
         "mediaType": "text/enriched",
         "protocol": "bep://"
      }
   }
}

上面例子是想象出来的, 如果作为baseURLhttps://example.org的站点的首页,当通过URL bep://example.org/myindex.enr访问时, Hugo会生成一个朴素的文本文件主页.

配置输出格式

下面是输出格式的配置选项的全部列表以及他们的默认值:

name
输出格式的标志符号. 用来定义页面的输出格式.
mediaType
必须与已经定义的媒体类型的Type匹配.
path
保存输出文件的sub path.
baseName
文件名称列表(首页等)的基础文件名称 默认值: index.
rel
可以用来在link 标签中创建 rel. 缺省值: alternate.
protocol
替换输出格式的baseURL中的"http://" 或者 “https://”.
isPlainText
如果为真, 将使用Go语言的朴素文本解析器解析模板. 缺省值: false.
isHTML
仅仅在类似HTML格式的情景中有关,比如 页面别名.

noUgly :当站点设置uglyURLstrue时, 关闭ugly URLs. 缺省值: false.

notAlternative
如果在页面(如Css)的AlternativeOutputFormats 格式列表中包含它无意义的化,设置这个变量为真。 注意这里我们使用条目 alternative 而不是alternate, 因为它没有必要会替换其他格式. enable if it doesn’t make sense to include this format in an AlternativeOutputFormats format listing on Page (e.g., with CSS). Note that we use the term alternative and not alternate here, as it does not necessarily replace the other format. 缺省值: false. ??
permalinkable
使得 .Permalink and .RelPermalink 返回呈现的输出格式而不是main(see below). 对HTMLAMP默认是启用的。 make .Permalink and .RelPermalink return the rendering Output Format rather than main (see below). This is enabled by default for HTML and AMP. 缺省值: false.

页面的输出格式

Hugo中页面可以在文件系统中呈现出多种输出格式。

默认的输出格式

每一页都有 Kind 属性, 默认的输出格式基于这个kind属性

KindDefault Output Formats
pageHTML
homeHTML, RSS
sectionHTML, RSS
taxonomyHTML, RSS
termHTML, RSS

定制输出格式 Customizing Output Formats

在页面的前言设定或者网站配置文件(对所有站点或者每个语言)中定义输出格式的outputs列表可以定制输出格式.

站点配置的例子:

config.
     
1
2
3
4
5
6
7
outputs:
  home:
  - HTML
  - AMP
  - RSS
  page:
  - HTML
1
2
3
[outputs]
  home = ["HTML", "AMP", "RSS"]
  page = ["HTML"]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
   "outputs": {
      "home": [
         "HTML",
         "AMP",
         "RSS"
      ],
      "page": [
         "HTML"
      ]
   }
}

注意上面例子中, section, taxonomyterm输出格式 仍然是它们的默认值["HTML", "RSS"].

We have fixed the before confusing page kinds used for taxonomies (see the listing below) to be in line with the terms used when we talk about taxonomies. We have been careful to avoid site breakage, and you should get an ERROR in the console if you need to adjust your outputs section.

KindDescriptionExample
homeThe landing page for the home page/index.html
pageThe landing page for a given pagemy-post page (/posts/my-post/index.html)
sectionThe landing page of a given sectionposts section (/posts/index.html)
taxonomyThe landing page for a taxonomytags taxonomy (/tags/index.html)
termThe landing page for one taxonomy’s termterm awesome in tags taxonomy (/tags/awesome/index.html)
  • 输出的定义是针对每一个 Page Kind (page, home, section, taxonomy, or term).
  • 输出格式的名称(如 HTML AMP)必须和定义的输出格式Name匹配The names.
  • 这些名称是大小写无关的.
  • 可以在内容页面的前言设定重载这个设置.

下面是一个内容文件的YAML前言设定的例子,定义了输出的Page的输出格式:

1
2
3
4
5
6
7
---
date: "2016-03-19"
outputs:
- html
- amp
- json
---

##输出格式的列表

每个页面都有.OutputFormats (所有格式, 包含当前的格式) 和 .AlternativeOutputFormats变量, 后者有助于在站点的<head>创建link rel的list:

1
2
3
{{ range .AlternativeOutputFormats -}}
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
{{ end -}}

输出格式的链接

页面的.Permalink.RelPermalink 会返回页面定义的输出格式中第一个(通常是HTML, 如果没有定义其他的)。这个调用它们的模板文件无关。

from single.json.json:

1
2
3
4
{{ .RelPermalink }} > /that-page/
{{ with  .OutputFormats.Get "json" -}}
{{ .RelPermalink }} > /that-page/index.json
{{- end }}

为了上面代码段返回的是当前模板文件的输出格式, 给定的输出格式应该设置permalinkable为true.

同上面一样的模板文件,设置了json输出格式的permalinkable为真:

1
2
3
4
{{ .RelPermalink }} > /that-page/index.json
{{ with  .OutputFormats.Get "html" -}}
{{ .RelPermalink }} > /that-page/
{{- end }}

在内容文件中,可以使用ref 或者 relref 短代码 :

1
2
[Neat]({{< ref "blog/neat.md" "amp" >}})
[Who]({{< relref "about.md#who" "amp" >}})

输出格式的模板

一个新的输出格式需要相应的模板,然后才能输出有用的内容。

下面列出了不同的输出格式的例子, 包括后缀、hugo的对应的模板查询顺序. 表内例子都可以:

ExampleOutputFormatSuffixTemplate Lookup Order
Single page in "posts" sectionHTMLhtml[layouts/posts/single.html.html layouts/posts/single.html layouts/_default/single.html.html layouts/_default/single.html]
Base template for single page in "posts" sectionHTMLhtml[layouts/posts/single-baseof.html.html layouts/posts/baseof.html.html layouts/posts/single-baseof.html layouts/posts/baseof.html layouts/_default/single-baseof.html.html layouts/_default/baseof.html.html layouts/_default/single-baseof.html layouts/_default/baseof.html]
Single page in "posts" section with layout setHTMLhtml[layouts/posts/demolayout.html.html layouts/posts/single.html.html layouts/posts/demolayout.html layouts/posts/single.html layouts/_default/demolayout.html.html layouts/_default/single.html.html layouts/_default/demolayout.html layouts/_default/single.html]
Base template for single page in "posts" section with layout setHTMLhtml[layouts/posts/demolayout-baseof.html.html layouts/posts/single-baseof.html.html layouts/posts/baseof.html.html layouts/posts/demolayout-baseof.html layouts/posts/single-baseof.html layouts/posts/baseof.html layouts/_default/demolayout-baseof.html.html layouts/_default/single-baseof.html.html layouts/_default/baseof.html.html layouts/_default/demolayout-baseof.html layouts/_default/single-baseof.html layouts/_default/baseof.html]
AMP single pageAMPhtml[layouts/posts/single.amp.html layouts/posts/single.html layouts/_default/single.amp.html layouts/_default/single.html]
AMP single page, French languageAMPhtml[layouts/posts/single.fr.amp.html layouts/posts/single.amp.html layouts/posts/single.fr.html layouts/posts/single.html layouts/_default/single.fr.amp.html layouts/_default/single.amp.html layouts/_default/single.fr.html layouts/_default/single.html]
Home pageHTMLhtml[layouts/index.html.html layouts/home.html.html layouts/list.html.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/index.html.html layouts/_default/home.html.html layouts/_default/list.html.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
Base template for home pageHTMLhtml[layouts/index-baseof.html.html layouts/home-baseof.html.html layouts/list-baseof.html.html layouts/baseof.html.html layouts/index-baseof.html layouts/home-baseof.html layouts/list-baseof.html layouts/baseof.html layouts/_default/index-baseof.html.html layouts/_default/home-baseof.html.html layouts/_default/list-baseof.html.html layouts/_default/baseof.html.html layouts/_default/index-baseof.html layouts/_default/home-baseof.html layouts/_default/list-baseof.html layouts/_default/baseof.html]
Home page with type setHTMLhtml[layouts/demotype/index.html.html layouts/demotype/home.html.html layouts/demotype/list.html.html layouts/demotype/index.html layouts/demotype/home.html layouts/demotype/list.html layouts/index.html.html layouts/home.html.html layouts/list.html.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/index.html.html layouts/_default/home.html.html layouts/_default/list.html.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
Base template for home page with type setHTMLhtml[layouts/demotype/index-baseof.html.html layouts/demotype/home-baseof.html.html layouts/demotype/list-baseof.html.html layouts/demotype/baseof.html.html layouts/demotype/index-baseof.html layouts/demotype/home-baseof.html layouts/demotype/list-baseof.html layouts/demotype/baseof.html layouts/index-baseof.html.html layouts/home-baseof.html.html layouts/list-baseof.html.html layouts/baseof.html.html layouts/index-baseof.html layouts/home-baseof.html layouts/list-baseof.html layouts/baseof.html layouts/_default/index-baseof.html.html layouts/_default/home-baseof.html.html layouts/_default/list-baseof.html.html layouts/_default/baseof.html.html layouts/_default/index-baseof.html layouts/_default/home-baseof.html layouts/_default/list-baseof.html layouts/_default/baseof.html]
Home page with layout setHTMLhtml[layouts/demolayout.html.html layouts/index.html.html layouts/home.html.html layouts/list.html.html layouts/demolayout.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/demolayout.html.html layouts/_default/index.html.html layouts/_default/home.html.html layouts/_default/list.html.html layouts/_default/demolayout.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
AMP home, French language"AMPhtml[layouts/index.fr.amp.html layouts/home.fr.amp.html layouts/list.fr.amp.html layouts/index.amp.html layouts/home.amp.html layouts/list.amp.html layouts/index.fr.html layouts/home.fr.html layouts/list.fr.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/index.fr.amp.html layouts/_default/home.fr.amp.html layouts/_default/list.fr.amp.html layouts/_default/index.amp.html layouts/_default/home.amp.html layouts/_default/list.amp.html layouts/_default/index.fr.html layouts/_default/home.fr.html layouts/_default/list.fr.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
JSON homeJSONjson[layouts/index.json.json layouts/home.json.json layouts/list.json.json layouts/index.json layouts/home.json layouts/list.json layouts/_default/index.json.json layouts/_default/home.json.json layouts/_default/list.json.json layouts/_default/index.json layouts/_default/home.json layouts/_default/list.json]
RSS homeRSSxml[layouts/index.rss.xml layouts/home.rss.xml layouts/rss.xml layouts/list.rss.xml layouts/index.xml layouts/home.xml layouts/list.xml layouts/_default/index.rss.xml layouts/_default/home.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/index.xml layouts/_default/home.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
RSS section postsRSSxml[layouts/posts/section.rss.xml layouts/posts/rss.xml layouts/posts/list.rss.xml layouts/posts/section.xml layouts/posts/list.xml layouts/section/section.rss.xml layouts/section/rss.xml layouts/section/list.rss.xml layouts/section/section.xml layouts/section/list.xml layouts/_default/section.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/section.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
Taxonomy in categoriesRSSxml[layouts/categories/category.terms.rss.xml layouts/categories/terms.rss.xml layouts/categories/taxonomy.rss.xml layouts/categories/rss.xml layouts/categories/list.rss.xml layouts/categories/category.terms.xml layouts/categories/terms.xml layouts/categories/taxonomy.xml layouts/categories/list.xml layouts/category/category.terms.rss.xml layouts/category/terms.rss.xml layouts/category/taxonomy.rss.xml layouts/category/rss.xml layouts/category/list.rss.xml layouts/category/category.terms.xml layouts/category/terms.xml layouts/category/taxonomy.xml layouts/category/list.xml layouts/taxonomy/category.terms.rss.xml layouts/taxonomy/terms.rss.xml layouts/taxonomy/taxonomy.rss.xml layouts/taxonomy/rss.xml layouts/taxonomy/list.rss.xml layouts/taxonomy/category.terms.xml layouts/taxonomy/terms.xml layouts/taxonomy/taxonomy.xml layouts/taxonomy/list.xml layouts/_default/category.terms.rss.xml layouts/_default/terms.rss.xml layouts/_default/taxonomy.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/category.terms.xml layouts/_default/terms.xml layouts/_default/taxonomy.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
Term in categoriesRSSxml[layouts/categories/term.rss.xml layouts/categories/category.rss.xml layouts/categories/taxonomy.rss.xml layouts/categories/rss.xml layouts/categories/list.rss.xml layouts/categories/term.xml layouts/categories/category.xml layouts/categories/taxonomy.xml layouts/categories/list.xml layouts/term/term.rss.xml layouts/term/category.rss.xml layouts/term/taxonomy.rss.xml layouts/term/rss.xml layouts/term/list.rss.xml layouts/term/term.xml layouts/term/category.xml layouts/term/taxonomy.xml layouts/term/list.xml layouts/taxonomy/term.rss.xml layouts/taxonomy/category.rss.xml layouts/taxonomy/taxonomy.rss.xml layouts/taxonomy/rss.xml layouts/taxonomy/list.rss.xml layouts/taxonomy/term.xml layouts/taxonomy/category.xml layouts/taxonomy/taxonomy.xml layouts/taxonomy/list.xml layouts/category/term.rss.xml layouts/category/category.rss.xml layouts/category/taxonomy.rss.xml layouts/category/rss.xml layouts/category/list.rss.xml layouts/category/term.xml layouts/category/category.xml layouts/category/taxonomy.xml layouts/category/list.xml layouts/_default/term.rss.xml layouts/_default/category.rss.xml layouts/_default/taxonomy.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/term.xml layouts/_default/category.xml layouts/_default/taxonomy.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
Section list for "posts" sectionHTMLhtml[layouts/posts/posts.html.html layouts/posts/section.html.html layouts/posts/list.html.html layouts/posts/posts.html layouts/posts/section.html layouts/posts/list.html layouts/section/posts.html.html layouts/section/section.html.html layouts/section/list.html.html layouts/section/posts.html layouts/section/section.html layouts/section/list.html layouts/_default/posts.html.html layouts/_default/section.html.html layouts/_default/list.html.html layouts/_default/posts.html layouts/_default/section.html layouts/_default/list.html]
Section list for "posts" section with type set to "blog"HTMLhtml[layouts/blog/posts.html.html layouts/blog/section.html.html layouts/blog/list.html.html layouts/blog/posts.html layouts/blog/section.html layouts/blog/list.html layouts/posts/posts.html.html layouts/posts/section.html.html layouts/posts/list.html.html layouts/posts/posts.html layouts/posts/section.html layouts/posts/list.html layouts/section/posts.html.html layouts/section/section.html.html layouts/section/list.html.html layouts/section/posts.html layouts/section/section.html layouts/section/list.html layouts/_default/posts.html.html layouts/_default/section.html.html layouts/_default/list.html.html layouts/_default/posts.html layouts/_default/section.html layouts/_default/list.html]
Section list for "posts" section with layout set to "demoLayout"HTMLhtml[layouts/posts/demolayout.html.html layouts/posts/posts.html.html layouts/posts/section.html.html layouts/posts/list.html.html layouts/posts/demolayout.html layouts/posts/posts.html layouts/posts/section.html layouts/posts/list.html layouts/section/demolayout.html.html layouts/section/posts.html.html layouts/section/section.html.html layouts/section/list.html.html layouts/section/demolayout.html layouts/section/posts.html layouts/section/section.html layouts/section/list.html layouts/_default/demolayout.html.html layouts/_default/posts.html.html layouts/_default/section.html.html layouts/_default/list.html.html layouts/_default/demolayout.html layouts/_default/posts.html layouts/_default/section.html layouts/_default/list.html]
Taxonomy list in categoriesHTMLhtml[layouts/categories/category.terms.html.html layouts/categories/terms.html.html layouts/categories/taxonomy.html.html layouts/categories/list.html.html layouts/categories/category.terms.html layouts/categories/terms.html layouts/categories/taxonomy.html layouts/categories/list.html layouts/category/category.terms.html.html layouts/category/terms.html.html layouts/category/taxonomy.html.html layouts/category/list.html.html layouts/category/category.terms.html layouts/category/terms.html layouts/category/taxonomy.html layouts/category/list.html layouts/taxonomy/category.terms.html.html layouts/taxonomy/terms.html.html layouts/taxonomy/taxonomy.html.html layouts/taxonomy/list.html.html layouts/taxonomy/category.terms.html layouts/taxonomy/terms.html layouts/taxonomy/taxonomy.html layouts/taxonomy/list.html layouts/_default/category.terms.html.html layouts/_default/terms.html.html layouts/_default/taxonomy.html.html layouts/_default/list.html.html layouts/_default/category.terms.html layouts/_default/terms.html layouts/_default/taxonomy.html layouts/_default/list.html]
Taxonomy term in categoriesHTMLhtml[layouts/categories/term.html.html layouts/categories/category.html.html layouts/categories/taxonomy.html.html layouts/categories/list.html.html layouts/categories/term.html layouts/categories/category.html layouts/categories/taxonomy.html layouts/categories/list.html layouts/term/term.html.html layouts/term/category.html.html layouts/term/taxonomy.html.html layouts/term/list.html.html layouts/term/term.html layouts/term/category.html layouts/term/taxonomy.html layouts/term/list.html layouts/taxonomy/term.html.html layouts/taxonomy/category.html.html layouts/taxonomy/taxonomy.html.html layouts/taxonomy/list.html.html layouts/taxonomy/term.html layouts/taxonomy/category.html layouts/taxonomy/taxonomy.html layouts/taxonomy/list.html layouts/category/term.html.html layouts/category/category.html.html layouts/category/taxonomy.html.html layouts/category/list.html.html layouts/category/term.html layouts/category/category.html layouts/category/taxonomy.html layouts/category/list.html layouts/_default/term.html.html layouts/_default/category.html.html layouts/_default/taxonomy.html.html layouts/_default/list.html.html layouts/_default/term.html layouts/_default/category.html layouts/_default/taxonomy.html layouts/_default/list.html]

Hugo的现在版本会检测部分模板的媒体类型和输出格式,如果可能的话,并且使用这些信息决定部分模板是否可以解析为纯文本模板。

Hugo会查找给定的名称,所以可以随意命名。但是如果你想文件被当成纯文本处理, 那么应该使用文件后缀,如果需要的化,还有输出格式的名称。 模式如下:

1
[partial name].[OutputFormat].[suffix]

下面例子的partial部分是一个纯文本模板(输出格式是CSV, 而且由于这是唯一具有后缀csv的输出格式, 我们不需要包含输出格式的Name):

1
{{ partial "mytextpartial.csv" . }}