Possible to sort range by multiple parameters?


#1

I hope this makes sense and I can get some help with an issue. I’m currently using Hugo for a company site. I have content under ‘products’ that represents a product category. Each page template for that content (single.html) then references all of the content under ‘product’ (individual product lines) whose tags match the current ‘product’ category. Then, in the template for each ‘products’ category, I use the following code to display all of the matching individual content under ‘product’ with the following script:

{{- $producttypeobj := . -}} <!-- Save alias for current product category page -->
{{- $prodtype := .Params.product -}} <!-- Get the product type that this product category page represents -->
	{{- $matchingProds := index .Site.Taxonomies.products $prodtype -}} <!-- Get all individual products in the 'products' taxonomy that match the current page's product type -->
	{{- range sort $matchingProds ".Page.Weight" -}} <!-- Sort by weight -->
		 {{- partial "product-card" (dict "Product" .Page "Products" $producttypeobj "currprodtype" $prodtype) -}} <!-- Display using a partial -->
	{{- end -}}

This seems to work fine. The issue I have, is not all of the individual products will have an assigned weight. It’s my understnading that Hugo will then default to sorting by date. But as these aren’t blog posts, but products, I would prefer that the secondary sorting param is ‘Title,’ not date. Is there any way to sort my index by weight, then title?

Thanks in advance!


#2

Interested on the topic, have you found any solution in the meanwhile?


#3

Hey. I haven’t worked on that part of our site for a while, so I’m a little foggy, but looking back through my scripts, it seems like I stopped using a taxonomy to accomplish this, and instead used arrays in the product category and individual product line frontmatter. Then, I used ‘intersect’ to grab any matching products, and sorted that range by title. It got me what I needed, though I’m not sure how helpful it’ll be to you:

                {{- $producttypeobj := . -}}
				<!-- Grab first prodtype from 'Products' param  -->
				{{- $prodtype := index .Params.products 0 -}}

				<!-- NOTE: Making 'products' param an array and using intersect below is a fix to replace the use of 'products' as a taxonomy. In theory, it should provide for each Product Type to call a number of products that would display on it. i.e. the 'emulsion_all' product type could simply list all the viable emulsion product types in the 'Params.products' array, instead of being a separate product type. -->
				{{ range sort (where .Site.Pages ".Params.products" "intersect" .Params.products) ".Title" }}
				  	{{ if ne .Permalink $.Permalink }} <!-- Ignore current page even though it technically matches the above criteria -->
				  		{{- partial "product-card" (dict "Product" . "Products" $producttypeobj "currprodtype" $prodtype) -}}
				  	{{ end }}
				{{ end }}

Thought it might be helpful to see an example of a page that this powers: https://nbcmeshtec.com/products/emulsion/all/

The product cards are displayed using this part of the script. They’re currently sorted by title.


#4

Mh, I see, don’t know if it will work for me.
My purpose is to order by weight first (as default) and by date second but ASC rather than DESC (as the default is) :frowning:️ don’t know if this is possible…

I don’t have entities like “products” to match to get the first level of order


#5

Yeah, I think I had a more flexible issue, and resolved it in a way you can’t. Sorry!


#6

No problem, thanks for your answering anyway ^^