Named queries

I have been getting my hands dirty with some “theme building” today (no, not team building …), and I come up a pattern I think could be useful to others.

So, in the theme’s config.toml:

[params]
[params.hero_queries]
[[params.hero_queries.featured_articles]]
key="Type"
operator="in"
match=["docs", "blog"]

And the partial func:

{{ $pages := slice }}
{{ $target := site.RegularPages }}
{{ range . }}
{{ $temp := slice }}
{{ if .operator }}
{{ $temp = where $target .key .operator .match }}
{{ else }}
{{ $temp = where $target .key .match }}
{{ end }}
{{ $pages = $pages | union $temp }}
{{ end }}
{{ return $pages }}

And then in the template:

{{ $pages := partial "funcs/build-query.html" site.Params.hero_queries.featured_articles }}
{{ range $pages }}
{{ end }}

Some comments to the above:

  • I have added these queries as a “theme scoped” params section to make it easy for people to override “just that section” and not everything. We might get more fine grained merges (there is an open issue about it), but I think splitting them and namespacing them makes it also easier to document/understand.
  • You can have a slice of queries per named quieries, the result will be unioned together.
  • The operator is optional
  • match can be a single value or a slice (for in)
1 Like

That’s interesting! Letting editors build their own queries…

Why the union if I may ask?

To remove duplicates

To be more verbose. The example above is not good. How about:

[params]
[params.hero_queries]
[[params.hero_queries.featured_articles]]
key="Type"
operator="in"
match=["docs", "blog"]
[[params.hero_queries.featured_articles]]
key="Type"
operator="="
match="blog"

Again, not the best example, but there will obviously be duplicates in the 2 queries above, and with the current template func this would be like “SQL select with OR”. We could expand the syntax above to:

[params]
[params.hero_queries]
[[params.hero_queries.featured_articles]]
key="Type"
operator="in"
match=["docs", "blog"]
[[params.hero_queries.featured_articles]]
key="Type"
operator="="
match="blog"
join="AND"

Which then would use the intersect func.

I see. Pretty advanced! Thanks.