Difficulty with iteration and Params

Hey there, so I have two main pages “category” and “product”. Categories contain products, and have an attribute prod_ids which contains an array of matching product_ids. From an individual product page, I want to be able to find the category that contains that product, then return 4 random products from that same category. What I have so far is:
{{ $prod_id := .Params.entity_id }} {{ range where .Site.Pages "Type" "category" }} {{ if in.Params.prod_ids $prod_id }} {{ $cat_id := .Params.entity_id }} {{ $cat_id }} {{ end }} {{ end }}
The problem with this so far is that, first, $cat_id contains two values – all_categories as well as the actual matching_category. How can I ignore all_categories or choose only the second value from the array? Also, when i’m iterating through something, why can’t I store the current value as $foo := . ? I was trying to do something like {{ if logic }} {{ $foo := . }} but I wasn’t returning the correct value. What I want to do is find the id of the category that matches, then iterate through category.prod_ids and .Render "li" for the first 4 of those. Can anyone offer me any guidance?

We could use more info. Can you post an example of your page front-matter?

You can do $foo = .. Can you show an example of it not working like you think should?

Have you considered using the Taxonomies features to handle your categories?

Embarrassingly, I have not really looked into taxonomies. I am pretty much done with my site except for this one feature, so I hadn’t really considered that I might need them. Specifically this is what I am trying to accomplish:

  1. Given a single.html of a product, find a category whose prod_ids contains that product
  2. iterate through that category’s prod_ids, choose 4 randomly that aren’t that product itself
  3. at the bottom of the single.html, display the “li.html” of those 4 prods that were chosen

So my logic is:

  1. store current product_id (entity_id)
  2. Iterate through all site pages and their prod_id arrays
  3. if cat contains prod_id, store that value
  4. iterate through those prod_ids, .Render “li.html” for first 4

The issue that I was having was that I was trying to do $cat := . if in .Params.prod_ids $prod_id and then do something like range first 4 $cat.prod_ids to get those corresponding first 4 product ids, which is returning no value.

I got it working,
{{ $prod_id := .Params.entity_id }} {{ range where .Site.Pages "Type" "category" }} {{ if and (ne .Params.entity_id "20") (in .Params.prod_ids $prod_id)}} {{ $cat_id := . }} {{ $prods := $cat_id.Params.prod_ids }} {{ range (where .Site.Pages "Type" "product") }} {{ if and (ne .Params.entity_id $prod_id) (in $prods .Params.entity_id) }} {{ .Render "li" }} {{ end }} {{ end }} {{ end }} {{ end }}

Last question though, How can I restrict the .Render "li" to only the first 4 elements? first 4 only seems to work as part of a range, but I want to first 4 only the matches.

You need to do your filtering prior to the range. Something like this (which I haven’t tested):

{{ range first 4 (where (where (where .Site.Pages "Type" "product") ".Params.entity_id" $prod_id) ".Params.entity_id" "in" $prods) }}
{{   .Render "li" }}
{{ end }}

The stacked where clauses can get confusing. You should be able to break those out into separate $x := where ... statements if you wanted to, but I haven’t tried that yet.