模板入門介紹
template(模板)是包�?template actions(模板動作)的文件,位於項目、主題或模塊�?layouts 目錄內�
模板使用 變量、函數 和 方法 將您的內容、資源和數據轉換為已發布的頁面。
Hugo 使用 Go 的 text/template 和 html/template 包。
text/template 包實現數據驅動的模板以生成文本輸出,而 html/template 包實現數據驅動的模板以生成 HTML 輸出,防止代碼注入。
默認情況下,Hugo 在渲染 HTML 文件時使用 html/template 包。
例如,此 HTML 模板初始化 $v1 和 $v2 變量,然後在 HTML 段落中顯示它們及其乘積。
{{ $v1 := 6 }}
{{ $v2 := 7 }}
<p>{{ $v1 }} 和 {{ $v2 }} 的乘積是 {{ 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>我的頁面標題</h2>
<p>foo</p>
<p>bar</p>
<p>baz</p>模板上下文
在 range 或 with 塊中,您可以通過在點前添加美元符號 ($) 來訪問傳遞給模板的上下文:
{{ with "foo" }}
<p>{{ $.Title }} - {{ . }}</p>
{{ end }}Hugo 將此渲染為:
<p>我的頁面標題 - foo</p>在繼續閱讀之前,請確保您徹底理解 上下文 的概念。新手用戶最常見的模板錯誤與上下文有關。
動作
在上面的示例中,成對的開始和結束大括號表示模板動作的開始和結束,模板動作是模板內的數據評估或控制結構。
模板動作可以包含字面值(布爾值、字符串、整數 和 浮點數)、當前上下文、變量、函數、方法 和 nil 關鍵字。
{{ $convertToLower := true }}
{{ if $convertToLower }}
<h2>{{ strings.ToLower .Title }}</h2>
{{ end }}在上面的示例中:
$convertToLower是一個變量true是一個字面布爾值if是控制結構的開始strings.ToLower是一個將所有字符轉換為小寫的函數Title是Page對象上的一個方法end是控制結構的結束
Hugo 將上述內容渲染為:
<h2>我的頁面標題</h2>
空白
注意到上一個示例中的空行和縮進了嗎?雖然在生產環境中通常會對輸出進行壓縮,因此這些空白無關緊要,但您可以使用帶連字符的模板動作分隔符來刪除相鄰的空白:
{{- $convertToLower := true -}}
{{- if $convertToLower -}}
<h2>{{ strings.ToLower .Title }}</h2>
{{- end -}}Hugo 將此渲染為:
<h2>我的頁面標題</h2>空白包括空格、水平制表符、回車符和換行符。
引號字符
Hugo 模板使用不同的引號字符來定義文本和字符的處理方式。
使用雙引號表示 解釋型字符串字面值。這些將反斜槓解釋為特殊指令:
{{ print "Hello world\u0021" }} → Hello world!使用反引號表示 原始字符串字面值。這些忽略反斜槓並按字面處理每個字符:
{{ print `Hello world\u0021` }} → Hello world\u0021使用單引號表示 rune 字面值。與字符串不同,這些將單個字符表示為其數字 Unicode 值:
{{ print '!' }} → 33實際上,您幾乎不會在模板代碼中使用 rune 字面值。它們最常用於低級編程;在 Hugo 模板中,您幾乎總是需要字符串。
管道
在模板動作中,您可以將值 管道 傳遞給函數或方法。管道值成為函數或方法的最後一個參數。例如,這些是等價的:
{{ 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.`
}}Nil
除了在比較中使用 nil 關鍵字外,您不能將其用作任何函數或方法的參數,也不能將其分配給變量。例如,這些是 nil 關鍵字的有效用法:
{{ if gt 42 nil }}
<p>42 大於 nil</p>
{{ end }}
{{ $pages := where .Site.RegularPages "Params.color" "ne" nil }}另一方面,這些是無效的:
{{ $a := nil }}
{{ add 3 nil }}
{{ nil | print}}上述動作會拋出錯誤。
變量
變量是用戶定義的 標識符,前面加上美元符號 ($),表示在模板動作中初始化或分配的任何數據類型的值。例如,$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切片和數組從零開始;元素 0 是第一個元素。
對於表示映射或對象的變量,鏈接 標識符以返回所需的值或訪問所需的方法。
{{ $map := dict "a" "foo" "b" "bar" "c" "baz" }}
{{ $map.c }} → baz
{{ $homePage := .Site.Home }}
{{ $homePage.Title }} → 我的主頁標題如上所示,對象和方法名稱是大寫的。雖然不要求,但為了避免混淆,我們建議變量和映射鍵名以小寫字母或下劃線開頭。
函數
函數在模板動作中使用,接受一個或多個參數並返回一個值。與方法不同,函數不與對象關聯。
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 }} → 我的站點標題
{{ .Page.Title }} → 我的頁面標題傳遞給大多數模板的上下文是 Page 對象,因此這等同於上一個示例:
{{ .Site.Title }} → 我的站點標題
{{ .Title }} → 我的頁面標題某些方法接受參數。用空格將參數與方法分開。例如:
{{ $page := .Page.GetPage "/books/les-miserables" }}
{{ $page.Title }} → 悲慘世界注釋
不要嘗試使用 HTML 注釋分隔符來注釋模板代碼。
Hugo 在渲染頁面時會刪除 HTML 注釋,但首先會評估 HTML 注釋分隔符內的任何模板代碼。根據 HTML 注釋分隔符內的模板代碼,這可能會導致意外結果或導致構建失敗。
模板注釋類似於模板動作。成對的開始和結束大括號表示注釋的開始和結束。例如:
{{/* 這是一個內聯注釋。*/}}
{{- /* 這是一個刪除相鄰空白的內聯注釋。*/ -}}注釋內的代碼不會被解析、執行或顯示。注釋可以是內聯的,如上所示,也可以是塊形式的:
{{/*
這是一個塊注釋。
*/}}
{{- /*
這是一個刪除相鄰空白的
塊注釋。
*/ -}}您不能將一個注釋嵌套在另一個注釋內。
要渲染 HTML 注釋,請將字符串傳遞給 safeHTML 模板函數。例如:
{{ "<!-- 我是一個 HTML 注釋。-->" | safeHTML }}
{{ printf "<!-- 這是 %s 站點。-->" .Site.Title | safeHTML }}包含
使用 template 函數包含一個或多個 Hugo 的 嵌入式模板:
{{ partial "google_analytics.html" . }}
{{ partial "opengraph" . }}
{{ partial "pagination.html" . }}
{{ partial "schema.html" . }}
{{ partial "twitter_cards.html" . }}使用 partial 或 partialCached 函數包含一個或多個 部分模板:
{{ partial "breadcrumbs.html" . }}
{{ partialCached "css.html" . }}在 layouts/_partials 目錄中創建您的 部分 模板。
在上面的示例中,請注意我們將當前上下文(點)傳遞給每個模板。
示例
這組簡化的示例展示了上述一些概念。有關具體示例,請參閱 函數、方法 和 模板 文檔。
條件塊
{{ $var := 42 }}
{{ if eq $var 6 }}
{{ print "var 是 6" }}
{{ else if eq $var 7 }}
{{ print "var 是 7" }}
{{ else if eq $var 42 }}
{{ print "var 是 42" }}
{{ else }}
{{ print "var 是其他值" }}
{{ 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>集合為空</p>
{{ end }}要循環指定次數:
{{ $s := slice }}
{{ range 3 }}
{{ $s = $s | append . }}
{{ end }}
{{ $s }} → [0 1 2]重新綁定上下文
{{ $var := "foo" }}
{{ with $var }}
{{ . }} → foo
{{ else }}
{{ print "var 是假值" }}
{{ end }}要測試多個條件:
{{ $v1 := 0 }}
{{ $v2 := 42 }}
{{ with $v1 }}
{{ . }}
{{ else with $v2 }}
{{ . }} → 42
{{ else }}
{{ print "v1 和 v2 是假值" }}
{{ end }}訪問站點參數
請參閱 Site 對象上的 Params 方法文檔。
使用此站點配置:
baseURL: https://example.org
params:
author:
email: jsmith@example.org
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: 地球上最好的 Widgets
title: ABC Widgets
baseURL = 'https://example.org'
title = 'ABC Widgets'
[params]
copyright-year = '2023'
subtitle = '地球上最好的 Widgets'
[params.author]
email = 'jsmith@example.org'
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": "jsmith@example.org",
"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": "地球上最好的 Widgets"
},
"title": "ABC Widgets"
}
通過鏈接標識符訪問自定義站點參數:
{{ .Site.Params.subtitle }} → 地球上最好的 Widgets
{{ .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: jsmith@example.org
name: John Smith
display_related: true
key-with-hyphens: 必須使用 index 函數
title: 年度會議
---+++
date = 2023-10-17T15:11:37-07:00
title = '年度會議'
[params]
display_related = true
key-with-hyphens = '必須使用 index 函數'
[params.author]
email = 'jsmith@example.org'
name = 'John Smith'
+++{
"date": "2023-10-17T15:11:37-07:00",
"params": {
"author": {
"email": "jsmith@example.org",
"name": "John Smith"
},
"display_related": true,
"key-with-hyphens": "必須使用 index 函數"
},
"title": "年度會議"
}
title 和 date 字段是標准 前言字段,而其他字段是用戶定義的。
{{ .Params.display_related }} → true
{{ .Params.author.email }} → jsmith@example.org
{{ .Params.author.name }} → John Smith在上面的模板示例中,每個鍵都是有效的標識符。例如,沒有鍵包含連字符。要訪問不是有效標識符的鍵,請使用 index 函數:
{{ index .Params "key-with-hyphens" }} → 必須使用 index 函數