collections.Where
语法
collections.Where COLLECTION KEY [OPERATOR] VALUE
返回值
any
别名
where
where 函数返回给定的集合,移除不满足比较条件的元素。比较条件由 KEY、OPERATOR 和 VALUE 参数组成。
collections.Where COLLECTION KEY [OPERATOR] VALUE
--------------------
comparison condition
如果您不提供 OPERATOR 参数,Hugo 将测试相等性。例如:
{{ $pages := where .Site.RegularPages "Section" "books" }}
{{ $books := where .Site.Data.books "genres" "suspense" }}
参数
where 函数接受三个或四个参数。OPERATOR 参数是可选的。
- 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。 >,gttrue报告给定字段值是否大于VALUE。<=,le- (
bool) 报告给定字段值是否小于或等于VALUE。 <,lt- (
bool) 报告给定字段值是否小于VALUE。 in- (
bool) 报告给定字段值是否是VALUE的成员。比较字符串与切片,或字符串与字符串。请参阅详细信息。 not in- (
bool) 报告给定字段值是否不是VALUE的成员。比较字符串与切片,或字符串与字符串。请参阅详细信息。 intersect- (
bool) 报告给定字段值(一个切片)是否与VALUE具有一个或多个相同的元素。请参阅详细信息。 likev0.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 }}
交集比较
将一个 切片 与另一个 切片 进行比较,返回具有公共值的集合元素。这通常用于比较分类术语。
例如,要返回一个页面集合,其中“genres”分类中的任何术语是 “suspense” 或 “romance”
{{ $books := where site.RegularPages "Section" "eq" "books" }}
{{ $genres := slice "suspense" "romance" }}
{{ $pages := where $books "Params.genres" "intersect" $genres }}
正则表达式比较
在 v0.116.0 中新增要返回一个页面集合,其中 “author” 页面参数以 “victor” 或 “Victor” 开头
{{ $pages := where .Site.RegularPages "Params.author" "like" `(?i)^victor` }}
在指定正则表达式时,使用原始字符串字面量(反引号),而不是解释的字符串字面量(双引号)来简化语法。使用解释的字符串字面量,您必须转义反斜杠。
Go 的正则表达式包实现了 RE2 语法。RE2 语法是 PCRE 接受的语法的子集,大致而言,并且有一些注意事项。请注意,不支持 RE2 \C 转义序列。
日期比较
预定义日期
有四个预定义的前置数据日期:date、publishDate、lastmod 和 expiryDate。无论前置数据格式(TOML、YAML 或 JSON)如何,这些都是 time.Time 值,允许精确比较。
例如,要返回一个在当前年份之前创建的页面集合
{{ $startOfYear := time.AsTime (printf "%d-01-01" now.Year) }}
{{ $pages := where .Site.RegularPages "Date" "lt" $startOfYear }}
自定义日期
对于自定义前置数据日期,比较取决于前置数据格式(TOML、YAML 或 JSON)。
使用 TOML,日期值是一等公民。TOML 有日期数据类型,而 JSON 和 YAML 没有。如果您引用 TOML 日期,则它是一个字符串。如果您不引用 TOML 日期值,则它是 time.Time 值,从而实现精确的比较。
在下面的 TOML 示例中,请注意 event date 未被引用。
+++
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 }}
空值比较
要返回一个页面集合,其中前置数据中存在 “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" }}
可移植部分比较
对于主题作者来说很有用,通过将 where 函数与 Site 对象上的 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>
要从布尔值不等式测试中排除具有未定义字段的页面
- 使用布尔值比较创建集合
- 使用空值比较创建集合
- 使用
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>