模板入门
模板是项目、主题或模块的 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
方法以返回在前置 matter 中定义的标题。
当前上下文可能会在模板中更改。例如,在模板顶部,上下文可能是一个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 .Site.Language.LanguageName .Site.Language.Lang }}
{{ $v := or
.Site.Language.LanguageName
.Site.Language.Lang
}}
您还可以将原始字符串字面量拆分为两行或多行。例如,以下代码等效
{{ $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
对象。这是每个对象可用的方法 的一小部分示例。
对象 | 方法 | 描述 |
---|---|---|
页面 |
Date |
返回给定页面的日期。 |
页面 |
Params |
返回在给定页面的前置 matter 中定义的自定义参数的映射。 |
页面 |
Title |
返回给定页面的标题。 |
站点 |
Data |
返回由 data 目录中的文件组成的 Data 结构。 |
站点 |
Params |
返回在站点配置中定义的自定义参数的映射。 |
站点 |
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 }} → Les Misérables
注释
模板注释类似于模板操作。成对的开始和结束大括号表示注释的开始和结束。例如
{{/* 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
方法的文档。
使用此前置 matter
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