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
。 >
,gt
true
报告给定字段值是否大于VALUE
。<=
,le
- (
bool
) 报告给定字段值是否小于或等于VALUE
。 <
,lt
- (
bool
) 报告给定字段值是否小于VALUE
。 in
- (
bool
) 报告给定字段值是否是VALUE
的成员。比较字符串与切片,或字符串与字符串。请参阅详细信息。 not in
- (
bool
) 报告给定字段值是否不是VALUE
的成员。比较字符串与切片,或字符串与字符串。请参阅详细信息。 intersect
- (
bool
) 报告给定字段值(一个切片)是否与VALUE
具有一个或多个相同的元素。请参阅详细信息。 like
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 }}
交集比较
将一个 切片
与另一个 切片
进行比较,返回具有公共值的集合元素。这通常用于比较分类术语。
例如,要返回一个页面集合,其中“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>