模板入门
模板是项目、主题或模块的 layouts 目录中的一个文件。模板使用 变量 、 函数 和 方法 将你的内容、资源和数据转换为已发布的页面。
例如,此 HTML 模板初始化 $v1
和 $v2
变量,然后在 HTML 段落中显示它们及其乘积。
{{ $v1 := 6 }}
{{ $v2 := 7 }}
<p>The product of {{ $v1 }} and {{ $v2 }} is {{ mul $v1 $v2 }}.</p>
虽然 HTML 模板最为常见,但你可以为任何 输出格式 创建模板,包括 CSV、JSON、RSS 和纯文本。
上下文
在创建模板之前,需要理解的最重要的概念是 上下文 ,即传递到每个模板中的数据。数据可以是简单值,或者更常见的是 对象 和相关的 方法 。
例如,单个页面的模板接收一个 Page
对象, Page
对象提供方法来返回值或执行操作。
当前上下文
在模板中,点 (.
) 代表当前上下文。
<h2>{{ .Title }}</h2>
在上面的示例中,点代表 Page
对象,我们调用它的 Title
方法来返回在 前置内容 中定义的标题。
当前上下文可能会在模板中发生更改。例如,在模板顶部,上下文可能是一个 Page
对象,但我们在 range
或 with
块中将上下文重新绑定到另一个值或对象。
<h2>{{ .Title }}</h2>
{{ range slice "foo" "bar" }}
<p>{{ . }}</p>
{{ end }}
{{ with "baz" }}
<p>{{ . }}</p>
{{ end }}
在上面的示例中,当我们遍历值的 切片 时,上下文会发生变化。在第一次迭代中,上下文是“foo”,在第二次迭代中,上下文是“bar”。在 with
块内,上下文是“baz”。Hugo 将以上内容渲染为:
<h2>My Page Title</h2>
<p>foo</p>
<p>bar</p>
<p>baz</p>
模板上下文
在 range
或 with
块中,可以通过在点前面添加美元符号 ($
) 来访问传递到模板的上下文:
{{ with "foo" }}
<p>{{ $.Title }} - {{ . }}</p>
{{ end }}
Hugo 将其渲染为:
<p>My Page Title - foo</p>
操作
在上面的示例中,成对的左大括号和右大括号表示模板操作的开始和结束,即模板中的数据评估或控制结构。
模板操作可以包含文字值( 布尔值 、 字符串 、 整数 和 浮点数 )、变量、函数和方法。
{{ $convertToLower := true }}
{{ if $convertToLower }}
<h2>{{ strings.ToLower .Title }}</h2>
{{ end }}
在上面的示例中:
$convertToLower
是一个变量true
是一个文字布尔值strings.ToLower
是一个将所有字符转换为小写的函数Title
是Page
对象上的一个方法
Hugo 将以上内容渲染为:
<h2>my page title</h2>
空格
注意前面示例中的空行和缩进?尽管在生产环境中(你通常会最小化输出)无关紧要,但你可以使用带有连字符的模板操作分隔符来删除相邻的空格:
{{- $convertToLower := true -}}
{{- if $convertToLower -}}
<h2>{{ strings.ToLower .Title }}</h2>
{{- end -}}
Hugo 将其渲染为:
<h2>my page title</h2>
空格包括空格、水平制表符、回车符和换行符。
管道
在模板操作中,你可以将值 管道 到函数或方法。管道值成为函数或方法的最终参数。例如,这些是等效的:
{{ strings.ToLower "Hugo" }} → hugo
{{ "Hugo" | strings.ToLower }} → hugo
你可以将一个函数或方法的结果管道到另一个函数或方法。例如,这些是等效的:
{{ strings.TrimSuffix "o" (strings.ToLower "Hugo") }} → hug
{{ "Hugo" | strings.ToLower | strings.TrimSuffix "o" }} → hug
这些也是等效的:
{{ mul 6 (add 2 5) }} → 42
{{ 5 | add 2 | mul 6 }} → 42
分行
你可以将模板操作分成两行或多行。例如,这些是等效的:
{{ $v := or $arg1 $arg2 }}
{{ $v := or
$arg1
$arg2
}}
你还可以将 原始字符串文字 分成两行或多行。例如,这些是等效的:
{{ $msg := "This is line one.\nThis is line two." }}
{{ $msg := `This is line one.
This is line two.`
}}
变量
变量是用美元符号 ($
) 开头的用户定义的 标识符 ,表示任何数据类型的值,在模板操作中初始化或赋值。例如, $foo
和 $bar
是变量。
使用 :=
初始化变量,使用 =
为已初始化的变量赋值。例如:
{{ $total := 3 }}
{{ range slice 7 11 21 }}
{{ $total = add $total . }}
{{ end }}
{{ $total }} → 42
在 if
、 range
或 with
块内初始化的变量的作用域限于该块。在这些块之外初始化的变量的作用域限于模板。
对于表示切片或映射的变量,使用 index
函数返回所需的值。
{{ $slice := slice "foo" "bar" "baz" }}
{{ index $slice 2 }} → baz
{{ $map := dict "a" "foo" "b" "bar" "c" "baz" }}
{{ index $map "c" }} → baz
对于表示映射或对象的变量, 链接 标识符以返回所需的值或访问所需的方法。
{{ $map := dict "a" "foo" "b" "bar" "c" "baz" }}
{{ $map.c }} → baz
{{ $homePage := .Site.Home }}
{{ $homePage.Title }} → My Homepage
函数
函数在模板操作中使用,它接受一个或多个参数并返回值。与方法不同,函数不与对象关联。
Go 的 text/template 和 html/template 包提供少量函数、运算符和语句供一般使用。有关详细信息,请参阅函数文档的 go-templates 部分。
Hugo 提供数百个按命名空间分类的自定义 函数 。例如, strings
命名空间包含这些函数和其他函数:
函数 | 别名 |
---|---|
strings.ToLower |
lower |
strings.ToUpper |
upper |
strings.Replace |
replace |
如上所示,常用函数都有一个别名。在模板中使用别名以减少代码长度。
调用函数时,用空格将参数与函数分开,并将参数彼此分开。例如:
{{ $total := add 1 2 3 4 }}
方法
方法在模板操作中使用,并与对象关联,它接受零个或多个参数,并返回一个值或执行一个操作。
最常访问的对象是 Page
和 Site
对象。这是每个对象可用的 方法 的一小部分示例。
对象 | 方法 | 描述 |
---|---|---|
Page |
Date |
返回给定页面的日期。 |
Page |
Params |
返回给定页面前置内容中定义的自定义参数映射。 |
Page |
Title |
返回给定页面的标题。 |
Site |
Data |
返回由 data 目录中的文件组成的结构。 |
Site |
Params |
返回在站点配置中定义的自定义参数映射。 |
Site |
Title |
返回在站点配置中定义的标题。 |
用点 (.
) 将方法链接到其对象,如下所示,记住前导点表示 当前上下文 。
{{ .Site.Title }} → My Site Title
{{ .Page.Title }} → My Page Title
传递到大多数模板的上下文是一个 Page
对象,因此这与前面的示例等效:
{{ .Site.Title }} → My Site Title
{{ .Title }} → My Page Title
有些方法需要参数。用空格将参数与方法分开。例如:
{{ $page := .Page.GetPage "/books/les-miserables" }}
{{ $page.Title }} → 《悲惨世界》
注释
模板注释类似于模板操作。成对的左大括号和右大括号表示注释的开始和结束。例如:
{{/* This is an inline comment. */}}
{{- /* This is an inline comment with adjacent whitespace removed. */ -}}
注释中的代码不会被解析、执行或显示。注释可以是内联的(如上所示),也可以是块形式的:
{{/*
This is a block comment.
*/}}
{{- /*
This is a block comment with
adjacent whitespace removed.
*/ -}}
你不能将一个注释嵌套在另一个注释中。
要渲染 HTML 注释,请通过 safeHTML
模板函数传递字符串。例如:
{{ "<!-- I am an HTML comment. -->" | safeHTML }}
{{ printf "<!-- This is the %s site. -->" .Site.Title | safeHTML }}
包含
使用 template
函数包含一个或多个 Hugo 的[嵌入式模板]:
{{ template "_internal/google_analytics.html" . }}
{{ template "_internal/opengraph" . }}
{{ template "_internal/pagination.html" . }}
{{ template "_internal/schema.html" . }}
{{ template "_internal/twitter_cards.html" . }}
使用 partial
或 partialCached
函数包含一个或多个[局部模板]:
{{ partial "breadcrumbs.html" . }}
{{ partialCached "css.html" . }}
在 layouts/partials 目录中创建你的局部模板。
示例
这组有限的牵强附会的示例演示了上面描述的一些概念。有关特定示例,请参阅 函数 、 方法 和 模板 文档。
条件块
{{ $var := 42 }}
{{ if eq $var 6 }}
{{ print "var is 6" }}
{{ else if eq $var 7 }}
{{ print "var is 7" }}
{{ else if eq $var 42 }}
{{ print "var is 42" }}
{{ else }}
{{ print "var is something else" }}
{{ end }}
逻辑运算符
{{ $v1 := true }}
{{ $v2 := false }}
{{ $v3 := false }}
{{ $result := false }}
{{ if and $v1 $v2 $v3 }}
{{ $result = true }}
{{ end }}
{{ $result }} → false
{{ if or $v1 $v2 $v3 }}
{{ $result = true }}
{{ end }}
{{ $result }} → true
循环
{{ $s := slice "foo" "bar" "baz" }}
{{ range $s }}
<p>{{ . }}</p>
{{ else }}
<p>The collection is empty</p>
{{ end }}
使用 seq
函数循环指定的次数:
{{ $total := 0 }}
{{ range seq 4 }}
{{ $total = add $total . }}
{{ end }}
{{ $total }} → 10
重新绑定上下文
{{ $var := "foo" }}
{{ with $var }}
{{ . }} → foo
{{ else }}
{{ print "var is falsy" }}
{{ end }}
要测试多个条件:
{{ $v1 := 0 }}
{{ $v2 := 42 }}
{{ with $v1 }}
{{ . }}
{{ else with $v2 }}
{{ . }} → 42
{{ else }}
{{ print "v1 and v2 are falsy" }}
{{ end }}
访问站点参数
请参阅 Site
对象上的 Params
方法的文档。
使用此站点配置:
baseURL: https://example.org
params:
author:
email: [email protected]
name: John Smith
copyright-year: "2023"
layouts:
rfc_1123: Mon, 02 Jan 2006 15:04:05 MST
rfc_3339: "2006-01-02T15:04:05-07:00"
subtitle: The Best Widgets on Earth
title: ABC Widgets
baseURL = 'https://example.org'
title = 'ABC Widgets'
[params]
copyright-year = '2023'
subtitle = 'The Best Widgets on Earth'
[params.author]
email = '[email protected]'
name = 'John Smith'
[params.layouts]
rfc_1123 = 'Mon, 02 Jan 2006 15:04:05 MST'
rfc_3339 = '2006-01-02T15:04:05-07:00'
{
"baseURL": "https://example.org",
"params": {
"author": {
"email": "[email protected]",
"name": "John Smith"
},
"copyright-year": "2023",
"layouts": {
"rfc_1123": "Mon, 02 Jan 2006 15:04:05 MST",
"rfc_3339": "2006-01-02T15:04:05-07:00"
},
"subtitle": "The Best Widgets on Earth"
},
"title": "ABC Widgets"
}
通过链接标识符来访问自定义站点参数:
{{ .Site.Params.subtitle }} → The Best Widgets on Earth
{{ .Site.Params.author.name }} → John Smith
{{ $layout := .Site.Params.layouts.rfc_1123 }}
{{ .Site.Lastmod.Format $layout }} → Tue, 17 Oct 2023 13:21:02 PDT
访问页面参数
请参阅 Page
对象上的 Params
方法的文档。
使用此前置内容:
date: 2023-10-17T15:11:37-07:00
params:
author:
email: [email protected]
name: John Smith
display_related: true
title: Annual conference
date = 2023-10-17T15:11:37-07:00
title = 'Annual conference'
[params]
display_related = true
[params.author]
email = '[email protected]'
name = 'John Smith'
{
"date": "2023-10-17T15:11:37-07:00",
"params": {
"author": {
"email": "[email protected]",
"name": "John Smith"
},
"display_related": true
},
"title": "Annual conference"
}
通过链接标识符来访问自定义页面参数:
{{ .Params.display_related }} → true
{{ .Params.author.name }} → John Smith