where.md (5164B)
1 ---
2 title: where
3 # linktitle: where
4 description: Filters an array to only the elements containing a matching value for a given field.
5 date: 2017-02-01
6 publishdate: 2017-02-01
7 lastmod: 2017-02-01
8 categories: [functions]
9 menu:
10 docs:
11 parent: "functions"
12 keywords: [filtering]
13 signature: ["where COLLECTION KEY [OPERATOR] MATCH"]
14 workson: [lists,taxonomies,terms,groups]
15 hugoversion:
16 relatedfuncs: [intersect,first,after,last]
17 deprecated: false
18 toc: true
19 needsexample: true
20 ---
21
22 `where` filters an array to only the elements containing a matching
23 value for a given field.
24
25 It works in a similar manner to the [`where` keyword in
26 SQL][wherekeyword].
27
28 ```go-html-template
29 {{ range where .Pages "Section" "foo" }}
30 {{ .Content }}
31 {{ end }}
32 ```
33
34 It can be used by dot-chaining the second argument to refer to a nested element of a value.
35
36 ```
37 +++
38 series: golang
39 +++
40 ```
41
42 ```go-html-template
43 {{ range where .Site.Pages "Params.series" "golang" }}
44 {{ .Content }}
45 {{ end }}
46 ```
47
48 It can also be used with the logical operators `!=`, `>=`, `in`, etc. Without an operator, `where` compares a given field with a matching value equivalent to `=`.
49
50 ```go-html-template
51 {{ range where .Pages "Section" "!=" "foo" }}
52 {{ .Content }}
53 {{ end }}
54 ```
55
56 The following logical operators are available with `where`:
57
58 `=`, `==`, `eq`
59 : `true` if a given field value equals a matching value
60
61 `!=`, `<>`, `ne`
62 : `true` if a given field value doesn't equal a matching value
63
64 `>=`, `ge`
65 : `true` if a given field value is greater than or equal to a matching value
66
67 `>`, `gt`
68 : `true` if a given field value is greater than a matching value
69
70 `<=`, `le`
71 : `true` if a given field value is lesser than or equal to a matching value
72
73 `<`, `lt`
74 : `true` if a given field value is lesser than a matching value
75
76 `in`
77 : `true` if a given field value is included in a matching value; a matching value must be an array or a slice
78
79 `not in`
80 : `true` if a given field value isn't included in a matching value; a matching value must be an array or a slice
81
82 `intersect`
83 : `true` if a given field value that is a slice/array of strings or integers contains elements in common with the matching value; it follows the same rules as the [`intersect` function][intersect].
84
85 ## Use `where` with `Booleans`
86 When using booleans you should not put quotation marks.
87 ```go-html-template
88 {{range where .Pages "Draft" true}}
89 <p>{{.Title}}</p>
90 {{end}}
91 ```
92
93
94 ## Use `where` with `intersect`
95
96 ```go-html-template
97 {{ range where .Site.Pages "Params.tags" "intersect" .Params.tags }}
98 {{ if ne .Permalink $.Permalink }}
99 {{ .Render "summary" }}
100 {{ end }}
101 {{ end }}
102 ```
103
104 You can also put the returned value of the `where` clauses into a variable:
105
106 {{< code file="where-intersect-variables.html" >}}
107 {{ $v1 := where .Site.Pages "Params.a" "v1" }}
108 {{ $v2 := where .Site.Pages "Params.b" "v2" }}
109 {{ $filtered := $v1 | intersect $v2 }}
110 {{ range $filtered }}
111 {{ end }}
112 {{< /code >}}
113
114 ## Use `where` with `first`
115
116 Using `first` and `where` together can be very
117 powerful. Below snippet gets a list of posts only from [**main
118 sections**](#mainsections), sorts it using the [default
119 ordering](/templates/lists/) for lists (i.e., `weight => date`), and
120 then ranges through only the first 5 posts in that list:
121
122 {{< code file="first-and-where-together.html" >}}
123 {{ range first 5 (where site.RegularPages "Type" "in" site.Params.mainSections) }}
124 {{ .Content }}
125 {{ end }}
126 {{< /code >}}
127
128 ## Nest `where` Clauses
129
130 You can also nest `where` clauses to drill down on lists of content by more than one parameter. The following first grabs all pages in the "blog" section and then ranges through the result of the first `where` clause and finds all pages that are *not* featured:
131
132 ```go-html-template
133 {{ range where (where .Pages "Section" "blog" ) "Params.featured" "!=" true }}
134 ```
135
136 ## Unset Fields
137
138 Filtering only works for set fields. To check whether a field is set or exists, you can use the operand `nil`.
139
140 This can be useful to filter a small amount of pages from a large pool. Instead of setting a field on all pages, you can set that field on required pages only.
141
142 Only the following operators are available for `nil`
143
144 * `=`, `==`, `eq`: True if the given field is not set.
145 * `!=`, `<>`, `ne`: True if the given field is set.
146
147 ```go-html-template
148 {{ range where .Pages "Params.specialpost" "!=" nil }}
149 {{ .Content }}
150 {{ end }}
151 ```
152
153 ## Portable `where` filters -- `site.Params.mainSections` {#mainsections}
154
155 **This is especially important for themes.**
156
157 To list the most relevant pages on the front page or similar, you
158 should use the `site.Params.mainSections` list instead of comparing
159 section names to hard-coded values like `"posts"` or `"post"`.
160
161 ```go-html-template
162 {{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
163 ```
164
165 If the user has not set this config parameter in their site config, it
166 will default to the _section with the most pages_.
167
168 The user can override the default:
169
170 {{< code-toggle file="config" >}}
171 [params]
172 mainSections = ["blog", "docs"]
173 {{< /code-toggle >}}
174
175 [intersect]: /functions/intersect/
176 [wherekeyword]: https://www.techonthenet.com/sql/where.php