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:
- Given a single.html of a product, find a category whose prod_ids contains that product
- iterate through that category’s prod_ids, choose 4 randomly that aren’t that product itself
- at the bottom of the single.html, display the “li.html” of those 4 prods that were chosen
So my logic is:
- store current product_id (entity_id)
- Iterate through all site pages and their prod_id arrays
- if cat contains prod_id, store that value
- 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.