Get intersection of pages two taxonomy terms

Assuming that .Params.language is english the code below will give me all content items with languages = ["english", ...]

{{ range (index .Site.Taxonomies.languages .Params.language )}}
    {{ .Render "list_item" }}
  {{ end }}

The code below will give me all the content items with categories = ["videos", ...]

{{ range (index .Site.Taxonomies.categories "videos" ) }}
    {{ .Render "list_item" }}
  {{ end }}

I am trying to get a range of content items with both languages = ["english", ...] and categories = ["videos", ...].

I’ve tried the code below. It doesn’t give any build errors, but no items are returned. Is intersect the right way to be trying to do this?

{{ range (intersect (index .Site.Taxonomies.languages .Params.language ) (index .Site.Taxonomies.categories "videos" ))}}
    {{ .Render "list_item" }}
  {{ end }}

Intersect is the right function. But I am not a fan of these glued-together-three-things-at-once-happening code lines :wink: They have no advantage and are hard to read should you have to look at that code again in two years.

Cut it in three pieces.

  1. you load all items whose language is .params.language
  2. you intersect this with all items, that are in category “videos”
  3. you range this collection.

This way you can debug the content of your current collection variable and see after which step it’s empty. Have a look at https://github.com/kaushalmodi/hugo-debugprint if not yet done. It’s great for drive-by-debugging of variables.

The intersect documentation page by the way has this construct:

{{ $pages := $pages | intersect (where .Site.RegularPages "Params.images" "!=" nil) }}

My guess is, that you cant intersect like intersect(list1,list2) but have to intersect like this: list1 | intersect list2. But that would become clear when you cut it :slight_smile:

I’ve done some testing, having split the function into three parts, but I’m still missing something. In the example below, I’m looking for the intersection of items with the categories foo and bar. I’m certain the one content item has those two categories, as below.

Content item 1

  +++
  categories = ["foo", "bar"]
  ...
  +++

Content item 2

  +++
  categories = ["foo"]
  ...
  +++

When checking the length of $foo and $bar I get the expected lengths, but nothing when trying to intersect.

  {{ $foo := (index .Site.Taxonomies.categories "foo" )}}
  {{ printf "%#v" (len $foo) }} // 2
  {{ $bar := (index .Site.Taxonomies.categories "bar" ) }}
  {{ printf "%#v" (len $bar) }} // 1
  {{ $intersected := $bar | intersect $foo }}
  {{ printf "%#v" (len $intersected }} // 0

If I intersect $foo with itself, I get 2 items as expected.

  {{ $intersected := $foo | intersect $foo }}
  {{ printf "%#v" (len $intersected }} // 2

Incidentally, running {{ printf "%#v" $foo }} outputs the following:

page.WeightedPages{page.WeightedPage{Weight:0, Page:(*hugolib.pageState)(0xc0045944e0), owner:(*hugolib.pageState)(0xc002b56150)}, page.WeightedPage{Weight:0, Page:(*hugolib.pageState)(0xc003778030), owner:(*hugolib.pageState)(0xc002b56150)}}

and running {{ printf "%#v" $bar }} outputs the following:

page.WeightedPages{page.WeightedPage{Weight:0, Page:(*hugolib.pageState)(0xc003778030), owner:(*hugolib.pageState)(0xc002b56300)}}

With the partial I linked above from kaushalmodi you can output the content of the variables. Check if the subitems you assume should be returned in the $foo and $bar intersection are indeed looking identical.

I think it would be best if you put a testing repo online so we can see your setup. Maybe something else is coming into play.

I wonder why one debug is returning two different object types.

Maybe I’m missing something about this use case, but it looks like two where clauses on .RegularPages would do it:

{{ $entries := where site.RegularPages ".Params.languages" "intersect" (slice "english") }}
{{ $entries = where $entries ".Params.categories" "intersect" (slice "video") }}
{{ range $entries }}
  {{ .Render "list_item" }}
{{ end }}
1 Like

The above worked, but with the edits below (“videos” and .Site.RegularPages). Thank you!

      {{ $entries := where .Site.RegularPages ".Params.languages" "intersect" (slice .Params.language) }}
      {{ $entries = where $entries ".Params.categories" "intersect" (slice "videos") }}
      {{ range $entries }}
        {{ .Render "list_item" }}
      {{ end }}
1 Like