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