Using "or" with "where"

Hi —

Have been searching for an answer to this to no avail. I’m trying to wrap my head around go/hugo template conditionals. I can’t seem to get the syntax right.

This works:
{{- range first 4 (where (where .Site.Pages "Section" "essays") ".Params.featured" true) | shuffle -}}

Showing me four random featured entries from my “essays” section of the website.

I’d like to show featured entries from both “essays” and “journal” but can’t seem to get it right. Intuitively it feels like this should work but I’m falling short:

{{- range first 4 (where (where or ( (.Site.Pages "Section" "essays") (.Site.Pages "Section" "journal") ) ) ".Params.featured" true) | shuffle -}}

… which consistently produces the error: “: wrong number of args for or: want at least 1 got 0”

Any ideas? I feel like I’m so close.

As an aside: I think a more comprehensive breakdown of template conditionals would be a welcome addition to the documentation. Happy to spearhead that initiative if I can wrap my head around why this is failing.

Thanks,
C

Of course, as soon as I posted I figured out another way of going at the problem:

{{ $posts := shuffle (where .Site.Pages ".Params.featured" true) }} {{ range first 4 $posts }}

Solves the issue (and ignores the proper filtering by section, but since only those two sections have “featured” posts it’s OK, but feels hacky and non-specific), but I’m still in the dark about how to structure that first query I posted up above. Any insight would be appreciated. Many thanks.

C

Regarding the or: I think there might be a comma missing between the essays and journal brackets?

For OR you will be much happier with:

Also see intersect for AND.

Thanks, Bep.

Sub-question that I also haven’t seen a good answer to, is there a more clear way to peek inside of and debug variables than the standard printf "%#v?

I ask because this doesn’t seem to be working:

{{ $essays := where .Site.Pages "Section" "in" (slice "essays" "journal") }}
{{ $essays := $essays | union (where .Site.Pages ".Params.featured" true) }}

This is producing an $essays variable, the first entries of which are pages of “essays” or “journal” AND “featured” but then the array continues, filled with the rest of the pages on the site that are not necessarily of essays, journal, or featured.

I guess I feel like learning what’s going on under the hood more easily would speed up debugging and understanding what’s happening with the arrays and operations.

C

And of course once again the second I hit reply I find the answer (is there a german word for this? hitting send and understanding something at once?) — I should have been using intersect.

For those following along, the final working code is:

{{ $essays := where .Site.Pages "Section" "in" (slice "essays" "journal") }}
{{ $essays := $essays | intersect (where .Site.Pages ".Params.featured" true) | shuffle }}

… to get a randomized selection of featured articles from both essays and journal.

I’m so used to other templating systems where all conditionals easily fall on a single line, and where not everything acts as a function. So the insight into breaking things up into individual pieces / lines wasn’t entirely obvious. (My “natural” way of writing the above would be: where $pages.section == ("essays" || "journal") && $pages.params.featured == true … )

So far, Go’s templating logic is the only real pain point I’ve run into rebuilding/refactoring my site in Hugo. I wonder if there’s an opportunity here to create a logic wrapper to abstract / simplify for more general use cases?

Thanks,
C

@cmod great this quite close with what i’m looking for, is it possible to add filter for taxonomies inside your code? (for example entries from essays and journal with certain categories)

I’m not using taxonomies but I imagine it just follows the pattern here: add a second line intersecting the results of the first line with something like (I don’t know the specific syntax so I’m just making this up): $essays := $essays | intersect (where Site.Taxonomies "in" (slice "category1" "category2" "category3"))

It looks like Hugo is most kind to this sort of layered / building up of logic over multiple lines. It also makes it easier to debug.

C

I struggled with this too, and so the debugprint.html partial was born :smile:

You should be able to use that partial to print any variable in the layout. If a matching type is supported, then the debug print is slightly tweaked to fit that, else it defaults to printing %#v.

I make heavy use of recursion in that partial. So a simple {{ partial "debugprint.html" .Params }} inside a single.html layout snowballs into this (the whole Page Params (Debug) section)!! :sunglasses:

  • Note : I specifically picked that example because it’s a test case where I pack in dozens of complicated front-matter parameters. The same debug info on a more regular page would look like this.
2 Likes

@kaushalmodi — oh, this is wonderful, thank you. I wonder why this isn’t part of the core package? Seems like it would alleviate a lot of pain points …