collections.Where
where
函數會返回給定的集合,並移除不滿足比較條件的元素。比較條件由 KEY
、OPERATOR
和 VALUE
參數組成:
collections.Where COLLECTION KEY [OPERATOR] VALUE
--------------------
比較條件
如果沒有提供 OPERATOR
參數,Hugo 會測試等值比較。例如:
{{ $pages := where .Site.RegularPages "Section" "books" }}
{{ $books := where .Site.Data.books "genres" "suspense" }}
參數
where
函數接受三個或四個參數。OPERATOR
參數是可選的。
- COLLECTION
- (
any
) 一個 [頁面集合] 或 [切片] 的 [映射]。
- KEY
- (
string
) 要與VALUE
比較的頁面或映射值的鍵。對於頁面集合,常見的比較鍵是Section
、Type
和Params
。要與頁面Params
映射中的成員比較,請 [鏈接] 子鍵,如下所示:
{{ $result := where .Site.RegularPages "Params.foo" "bar" }}
- OPERATOR
- (
string
) 邏輯比較 運算符。 - VALUE
- (
any
) 要比較的值。要比較的值必須具有可比較的資料類型。例如:
比較 | 結果 |
---|---|
"123" "eq" "123" |
true |
"123" "eq" 123 |
false |
false "eq" "false" |
false |
false "eq" false |
true |
當其中一個或兩個要比較的值為切片時,請使用 in
、not in
或 intersect
運算符,如下所示。
運算符
使用以下任意邏輯運算符:
=
,==
,eq
- (
bool
) 報告給定欄位值是否等於VALUE
。 !=
,<>
,ne
- (
bool
) 報告給定欄位值是否不等於VALUE
。 >=
,ge
- (
bool
) 報告給定欄位值是否大於或等於VALUE
。 >
,gt
true
報告給定欄位值是否大於VALUE
。<=
,le
- (
bool
) 報告給定欄位值是否小於或等於VALUE
。 <
,lt
- (
bool
) 報告給定欄位值是否小於VALUE
。 in
- (
bool
) 報告給定欄位值是否是VALUE
的成員。比較字串對切片或字串對字串。請參見 詳細信息。 not in
- (
bool
) 報告給定欄位值是否不是VALUE
的成員。比較字串對切片或字串對字串。請參見 詳細信息。 intersect
- (
bool
) 報告給定欄位值(切片)是否包含與VALUE
共有的元素。請參見 詳細信息。 like
New in v0.116.0- (
bool
) 報告給定欄位值是否符合VALUE
中指定的正則表達式。使用like
運算符比較string
值。當將其他資料類型與正則表達式比較時,like
運算符會返回false
。
字串比較
比較給定欄位的值與 string
:
{{ $pages := where .Site.RegularPages "Section" "eq" "books" }}
{{ $pages := where .Site.RegularPages "Section" "ne" "books" }}
數字比較
{{ $books := where site.RegularPages "Section" "eq" "books" }}
{{ $pages := where $books "Params.price" "eq" 42 }}
{{ $pages := where $books "Params.price" "ne" 42.67 }}
{{ $pages := where $books "Params.price" "ge" 42 }}
{{ $pages := where $books "Params.price" "gt" 42.67 }}
{{ $pages := where $books "Params.price" "le" 42 }}
{{ $pages := where $books "Params.price" "lt" 42.67 }}
布林值比較
比較給定欄位的值與 bool
:
{{ $books := where site.RegularPages "Section" "eq" "books" }}
{{ $pages := where $books "Params.fiction" "eq" true }}
{{ $pages := where $books "Params.fiction" "eq" false }}
{{ $pages := where $books "Params.fiction" "ne" true }}
{{ $pages := where $books "Params.fiction" "ne" false }}
成員比較
例如,要返回一個頁面集合,其中 color
頁面參數是 “red” 或 “yellow”:
{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }}
{{ $colors := slice "red" "yellow" }}
{{ $pages := where $fruit "Params.color" "in" $colors }}
要返回一個頁面集合,其中 “color” 頁面參數既不是 “red” 也不是 “yellow”:
{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }}
{{ $colors := slice "red" "yellow" }}
{{ $pages := where $fruit "Params.color" "not in" $colors }}
交集比較
比較 slice
和 slice
,返回具有共同值的集合元素。這通常用於比較分類法術語。
例如,要返回一個頁面集合,其中 “genres” 分類法中的任何術語為 “suspense” 或 “romance”:
{{ $books := where site.RegularPages "Section" "eq" "books" }}
{{ $genres := slice "suspense" "romance" }}
{{ $pages := where $books "Params.genres" "intersect" $genres }}
正則表達式比較
New in v0.116.0要返回一個頁面集合,其中 “author” 頁面參數以 “victor” 或 “Victor” 開頭:
{{ $pages := where .Site.RegularPages "Params.author" "like" `(?i)^victor` }}
在指定正則表達式時,請使用原始的 string literal(反引號),而非解釋過的字串字面量(雙引號),以簡化語法。使用解釋過的字串字面量時,您必須對反斜線進行轉義。
Go 的正則表達式套件實現了 [RE2 語法]。RE2 語法是接受的 PCRE 語法的一個子集,粗略來說,並且有各種 caveats。請注意,RE2 不支援 \C
轉義序列。
日期比較
預設日期
有四個預設的 Front Matter 日期:date
、publishDate
、lastmod
和 expiryDate
。無論使用何種 Front Matter 資料格式(TOML、YAML 或 JSON),這些都是 time.Time
類型值,可以進行精確的比較。
例如,返回創建時間早於當前年份的頁面集合:
{{ $startOfYear := time.AsTime (printf "%d-01-01" now.Year) }}
{{ $pages := where .Site.RegularPages "Date" "lt" $startOfYear }}
自訂日期
使用自訂的 front matter 日期時,比較操作會依照 front matter 數據格式(TOML、YAML 或 JSON)來決定。
在 TOML 格式中,日期值是第一類別(first-class)。TOML 擁有日期數據類型,而 JSON 和 YAML 沒有。如果您引用 TOML 日期,它會是字串。如果您不引用 TOML 日期值,它將會是 time.Time
型別,從而可以進行精確的比較。
在下列的 TOML 範例中,請注意事件日期並未被引用。
+++
title = '2024 User Conference'
eventDate = 2024-04-01
+++
要返回一組未來的事件:
{{ $events := where .Site.RegularPages "Type" "events" }}
{{ $futureEvents := where $events "Params.eventDate" "gt" now }}
當使用 YAML、JSON 或引用的 TOML 值時,自訂日期會是字串;您無法將它與 time.Time
型別的值進行比較。如果自訂日期格式在不同頁面間一致,則可以進行字串比較。為了保險起見,透過遍歷整個集合來過濾頁面:
{{ $events := where .Site.RegularPages "Type" "events" }}
{{ $futureEvents := slice }}
{{ range $events }}
{{ if gt (time.AsTime .Params.eventDate) now }}
{{ $futureEvents = $futureEvents | append . }}
{{ end }}
{{ end }}
Nil 比較
要返回一組包含 “color” 參數的頁面,並與 nil
比較:
{{ $pages := where .Site.RegularPages "Params.color" "ne" nil }}
要返回一組不包含 “color” 參數的頁面,並與 nil
比較:
{{ $pages := where .Site.RegularPages "Params.color" "eq" nil }}
在上述的範例中,請注意 nil
並未被引用。
嵌套比較
以下兩者等價:
{{ $pages := where .Site.RegularPages "Type" "tutorials" }}
{{ $pages = where $pages "Params.level" "eq" "beginner" }}
{{ $pages := where (where .Site.RegularPages "Type" "tutorials") "Params.level" "eq" "beginner" }}
可攜式區塊比較
對於主題作者來說,可以避免硬編碼區塊名稱,透過在 Site
物件上使用 where
函數與 MainSections
方法來達成。
{{ $pages := where .Site.RegularPages "Section" "in" .Site.MainSections }}
通過這個結構,主題作者可以指示使用者在站點配置中指定主區塊:
params:
mainSections:
- blog
- galleries
[params]
mainSections = ['blog', 'galleries']
{
"params": {
"mainSections": [
"blog",
"galleries"
]
}
}
如果 params.mainSections
在站點配置中未被定義,則 MainSections
方法會返回一個包含單一元素的切片—即包含最多頁面的頂層區塊。
布林值/未定義比較
考慮以下網站內容:
content/
├── posts/
│ ├── _index.md
│ ├── post-1.md <-- front matter: exclude = false
│ ├── post-2.md <-- front matter: exclude = true
│ └── post-3.md <-- front matter: exclude not defined
└── _index.md
前兩個頁面有 “exclude” 欄位,但最後一個頁面並未定義這個欄位。在進行 相等 測試時,第三個頁面將 被排除;進行 不等 測試時,第三個頁面將 被包含。
相等測試
此模板:
<ul>
{{ range where .Site.RegularPages "Params.exclude" "eq" false }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>
將渲染為:
<ul>
<li><a href="/posts/post-1/">Post 1</a></li>
</ul>
此模板:
<ul>
{{ range where .Site.RegularPages "Params.exclude" "eq" true }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>
將渲染為:
<ul>
<li><a href="/posts/post-2/">Post 2</a></li>
</ul>
不等測試
此模板:
<ul>
{{ range where .Site.RegularPages "Params.exclude" "ne" false }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>
將渲染為:
<ul>
<li><a href="/posts/post-2/">Post 2</a></li>
<li><a href="/posts/post-3/">Post 3</a></li>
</ul>
此模板:
<ul>
{{ range where .Site.RegularPages "Params.exclude" "ne" true }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>
將渲染為:
<ul>
<li><a href="/posts/post-1/">Post 1</a></li>
<li><a href="/posts/post-3/">Post 3</a></li>
</ul>
排除未定義欄位的頁面,進行布林 不相等 測試:
- 使用布林比較創建集合
- 使用
nil
比較創建集合 - 使用
collections.Complement
函數將第二個集合從第一個集合中扣除。
範例模板:
{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" true }}
{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }}
<ul>
{{ range $p1 | complement $p2 }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>
渲染後結果為:
<ul>
<li><a href="/posts/post-1/">Post 1</a></li>
</ul>
範例模板:
{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" false }}
{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }}
<ul>
{{ range $p1 | complement $p2 }}
<li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
{{ end }}
</ul>
渲染後結果為:
<ul>
<li><a href="/posts/post-1/">Post 2</a></li>
</ul>
這樣的做法是將兩組頁面進行分開:一組具有布林 exclude
欄位,另一組 exclude
欄位未定義,再將未定義欄位的集合從布林比較結果中扣除,以達到想要的過濾邏輯。