計算和比較
Hugo 沒有 +、< 這些符號,比較需用函式呼叫。
{{ add 1 1 }}
{{ sub 2 1 }}
{{ mul 2 2 }}
{{ div 4 2 }}
{{ eq 1 1 }}
{{ ne 1 2 }}
{{ lt 1 2 }}
{{ le 2 2 }}
{{ gt 3 2 }}
{{ ge 2 2 }}2
1
4
2
true
true
true
true
true
trueif / else if / else
基本的 if-else 語法。false、空字串、0、nil、空 slice、空字典都是 falsy value。
{{ $x := 7 }}
{{ if eq $x 6 }}
eq 6
{{ else if eq $x 7 }}
eq 7
{{ else }}
...
{{ end }}eq 7with / else with
if 只判斷條件,不改變上下文,with 判斷條件之外,還把上下文換成該值本身。
{{ $v1 := "" }}
{{ $v2 := "橘子" }}
{{ with $v1 }}
{{ . }}
{{ else with $v2 }}
{{ . }}
{{ else }}
都不是
{{ end }}橘子and / or / not
邏輯判斷。
{{ and true false }}
{{ or true false }}
{{ not false }}false
true
truerange
range 等同於 for loop,Hugo 只有 for loop 沒有 while loop。
{{ range slice "蘋果" "香蕉" "橘子" }}
{{ . }}<br>
{{ end }}蘋果<br>
香蕉<br>
橘子<br>或是包含計數索引
{{ range $idx, $val := slice "蘋果" "香蕉" "橘子" }}
{{ $idx }}: {{ $val }}<br>
{{ end }}0: 蘋果<br>
1: 香蕉<br>
2: 橘子<br>break / continue
continue 讓迴圈跳過該次循環,break 終止迴圈。
{{ range slice "蘋果" "香蕉" "橘子" }}
{{ if eq . "香蕉" }}
{{ continue }}
{{ end }}
{{ if eq . "橘子" }}
{{ break }}
{{ end }}
{{ . }}
{{ end }}蘋果slice
slice 是一個列表,使用 index 取出元素,使用 len 取出長度。
{{ $s := slice 1 2 3 4 5 6 7 8 9 10 }}
{{ index $s 0 }}
{{ len $s }}1
10如要取範圍區間,可以使用 after/first 方式
{{ $s | first 5 | after 2 }}[3 4 5]seq
建立列表,seq N 產生 1 到 N 的整數列表,seq A B 產生 A 到 B。
{{ range seq 3 }}{{ . }}{{ end }}
{{ range seq 2 5 }}{{ . }}{{ end }}123
2345dict
dict(map)是一個鍵值對(key-value pair),鍵可以用點語法直接取值,效果跟 index 相同。
{{ $person := dict "name" "John" "age" 20 }}
{{ index $person "name" }}
{{ $person.name }}John
John取用不存在的鍵不會報錯。
cast
變數型別轉換。
{{ $s := "42" }}
{{ $n := cast.ToInt $s }}
{{ add $n 8 }}50add "42" 8 會拋出型別錯誤,因為 add 要求兩個運算元都是數字,字串必須先用 cast.ToInt 轉型。
partial 與 return
partial 呼叫模板檔案。
語法
{{ partial LAYOUT CONTEXT }}描述
partial 是獨立的模板檔案。用 partial 函式呼叫模板(LAYOUT)時,CONTEXT 會成為該檔案裡的 .。
{{ if lt . 100 }}
<span>特價</span>
{{ else }}
<span>原價</span>
{{ end }}{{ partial "price-tag.html" 80 }}<span>特價</span>若模板中沒有 return,Hugo 會將模板渲染為 HTML。若有 return,Hugo 則回傳該值:
{{ return lt . 100 }}{{ $cheap := partial "is-cheap.html" 80 }}
{{ print $cheap }}truev0.166.0 之前只支援一個 return。
傳入多個值
partial 只接收一個 CONTEXT 參數。若需要同時傳入重量和城市,用 dict 將兩者包成一個值:
{{ if ge .weight 5 }}
{{ .city }}:超重加收運費
{{ else }}
{{ .city }}:一般運費
{{ end }}{{ partial "shipping-note.html" (dict "weight" 6 "city" "TX") }}TX:超重加收運費.weight 與 .city 對應呼叫時 dict 裡的鍵。
就地定義
用 define 可將 partial 直接寫在呼叫它的模板裡:
{{ partial "inline" 21 }}
{{ define "_partials/inline/double" }}
{{ mul . 2 }}
{{ end }}42Hugo 在渲染前會先掃描所有可用模板,因此就地定義沒有先後順序的限制。就地定義的模板全站皆可呼叫。
模板間傳值
模板之間只能透過 {{ partial "foo.html" CONTEXT }} 傳遞的 CONTEXT 傳值,或是使用 .Store:用 .Store.Set 設定值,用 .Store.Get 取值。
partialCached 快取模板
partialCached 呼叫模板並快取其輸出結果。
語法
{{ partialCached LAYOUT CONTEXT [KEY1 KEY2 KEY3 ...] }}描述
當 LAYOUT 的輸出結果重複,且渲染該模板已構成效能瓶頸時,可用 partialCached 取代 partial,將輸出結果快取起來,避免重複計算。
KEY1、KEY2、KEY3……為選填的額外快取鍵(cache key),用來讓同一個 LAYOUT 依不同條件產生多組快取結果。額外的快取鍵不參與模板本身的計算,僅作為區分快取結果之用;其數量可為零個或多個。
若未指定任何額外快取鍵,快取鍵即為 LAYOUT 本身(也就是該 partial 的名稱)。
Hugo 平行渲染多個頁面。第一次呼叫某個快取鍵時,Hugo 尚未完成該快取鍵的儲存,因此在此之前平行執行的其他頁面仍會各自重新渲染同一個模板。快取鍵儲存完成後,後續呼叫才會直接使用快取結果。
每個 site 的快取各自獨立。
.Store
前面介紹的都是函式 function,.Store 則是方法 method,方法是需要綁定在物件上的,因此可以看到有 . 存在。
.Store 用於將內容儲存在目標物件上,用於在模板間傳值。.Store 可以在以下幾個物件中被呼叫:
| 作用域 | 使用方式 |
|---|---|
| 全站 | hugo.Store |
| 當前站1 | SITE.Store |
| 當前頁面 | PAGE.Store |
| 短碼 | SHORTCODE.Store |
| 區域變數 | collections.NewScratch |
.Store 有順序關係,若呼叫 .Get 之前尚未呼叫過 .Store,.Get 就沒有值。
.Store 內容的生命週期是整個程式週期,不會因為當前頁面渲染結束就被回收。
.Store 本身有眾多 method 可調用,所有 .Store 的方法都相同,只是 .Store 綁定的物件不同。
Example: 頁面初始化
若頁面有繁瑣的初始化,且多個模板都需要用到初始化後的結果,可以在 baseof.html 最前面初始化,並且以 .Page.Store 儲存,就能在每個 partial 模板取用 .Store 結果。
<!doctype html>
{{- partial "init.html" . -}}
<html>
...
</html>{{- with resource.Get "..." -}}
{{- ... -}}
{{- .Page.Store.Set "key" ... -}}
{{- end -}}{{ with .Page.Store.Get "key" }}
{{ ... }}
{{ end }}{{ with .Page.Store.Get "key" }}
{{ ... }}
{{ end }}Example: 呼叫計數
在同一個頁面中記錄 shortcode 被呼叫了多少次。
{{ $count := .Page.Store.Get "imageCounter" | default 0 }}
{{ $count = add $count 1 }}
{{ .Page.Store.Set "imageCounter" $count }}
<figure id="img-{{ $count }}">
<img src="{{ .Get "src" }}" alt="{{ .Get "alt" }}">
</figure>如果不需要計數,只需要查詢是否被呼叫,則可以用 .Page.HasShortcode 方法,此方法和 .Store 不同,沒有順序問題,因為 Hugo 會提前掃描一次 Markdown 文件,因此無須等到 shortcode 真的被渲染之後才使用 .Page.HasShortcode。
Example: 資源載入
一個常見的範例是呼叫 .Page.Store.Set,在該頁面記錄某功能被呼叫,就可以在該呼叫之後使用 .Page.Store.Get 執行對應邏輯。經典的使用範例如官方文檔中的 Mermaid 圖表。
當前站的意思請見 Sites Matrix 說明。 ↩︎