How do I create a content filter

I need help with creating a content filter for my project.

I would like users to be able to select a location and then a product type and get all products that match the specified location and product type. Right now, I’ve got the location filer working, but I don’t know how to make the product type filter work.

Content structure:

content
  pen
   pen1.md
   pen2.md
   _index.md
 pencil
   pencil1.md
   pencil2.md
   _index.md
 fountain-pen
   fountain-pen1.md
   fountain-pen2.md
   _index.md
 boston.md
 newyork.md

Each file in a section (pen, pencil, fountain-pen) has the following front matter:

+++
company = ""
date = ""
description = ""
locations = [""]
productType = ""
title = ""
website = ""
+++

The productType is either pen, pencil or fountain pen.

Each single page file (boston.md, newyork.md) has the following front matter:

+++
date = ""
metadescription = ""
title = ""
type = "location"
+++

In index.html I show a list of all the pens, pencils and fountain pens.

{{range (where .Site.RegularPages "Type" "not in" "location")}}
  {{partial "products.html" .}}
 {{end}}

I also have a location filter where all locations of each item is listed that I have created manually. This is done by creating a single page file for each location (boston.md, newyork.md).

   {{range (where .Site.RegularPages "Type" "in" "location")}}
     <a href="{{.Permalink}}">{{.Title}}</a>
   {{end}}

Once a user clicks on a location, such as Boston, the following code is generated in layouts > location > single.html:

{{$fileName := title (humanize .File.TranslationBaseName)}}
{{range (where .Site.RegularPages "Type" "not in" "location")}}
  {{if in .Params.locations $fileName}}
    {{partial "products.html" .}}
  {{end}}    
{{end}}

This shows all products for Boston and has a url http://localhost:1313/boston/. On this page, I would like to have a filter so a user can click on pen, pencil or fountain pen. If a user clicks on pen, the url changes to http://localhost:1313/boston/pen/ and shows all pens for Boston.

Not sure if this is important for you to know, but I will have 8 product types (pen, pencil etc) and 6-8 locations.

I’m sure this is possible, but I’m on the edge of my abilities here. So help, please?

Have you looked into setting up custom taxonomies for this? Perhaps it will work for your use case:

Yes, but I’m not sure how taxonomies will help. If I understand correctly, with a taxonomy I can filter content to location which I’ve already managed to do. But I won’t be able to use taxonomies to filter location and then filter product type. It will just be two separate content filters.

It’s not as straightforward as you may think to achieve what you want with your current content structure.

I find it interesting that you are using a single page to render all products from a given location and not Taxonomies. But to achieve a URL like http://localhost:1313/boston/pen/ you really need to create some Taxonomies.

Since all your posts have already a locations front-matter parameter assigned I would do the following

In config.toml I would define

[taxonomies]
    locations = "locations"

Then I would create a folder under /content/locations/

Inside this folder I would create a blank _index.md

Then another folder under /content/locations/boston/ (ditto for NY)

In here I would also create another blank _index.md

And then I would create another folder under /content/fountain-pen/boston/ (same for other products locations)

And within this folder I would create an _index.md with the following:

---
title: ....
description: .....
location: boston
---

Note that in the above front-matter parameter location is in the singular.

Then under /default/layouts/list.html I would add the following:

{{ $taxa:= .Params.location }}
{{- with $taxa -}}
{{- range ($.Site.GetPage "taxonomy" "locations" $taxa).Pages -}}
 HTML goes here
	{{- end -}} 
 {{- end -}} 

And you will end up having your desired URL with the list of products from a certain location.

PS. This is not the official Hugo way of listing content. But it gets the job done and the final URL will be sparkling clean.

Thanks for this. I’ll give this a try.

One issue I see with your approach, is the amount of folders I’ll need to create. With 8 product types and 6-8 locations, that’s a whole lot of folders.

It is a whole lot of folders indeed. But your alternatives are either re-organize your content in nested sections per city, or use Hugo taxonomies the traditional way and you will end up with a URL like http://localhost:1313/tag/bostonpen/

It’s your call what you prefer to do.

Understood.

The problem with nested sections per city is that one product might be available in several locations.

If I use taxonomies the traditional way, how will that allow me to filter products by location or the other way around? Am I wrong that if I create locations and product types as taxonomies I will be able to click on a location and then click on a product type and get all pens in Boston? I thought I would only be able to get one or the other

Basically what I’m trying to create is something similar to this: https://www.ironsrc.com/jobs/

You can select where you want to work (location) and then you can select a department (product type) for that location

Simple. You can add a different tag in your products i.e. bostonpen or newyorkpen And then Hugo will create that taxonomy term page for you.

Alright, thanks. That seems like a much better approach.

Not sure if you saw my edit, but this is basically what I’m trying to create as a content filter:

https://www.ironsrc.com/jobs/

You can select where you want to work (location) and then you can select a department (product type) for that location

Yes I saw your edit. But the content filter on that page seems like it’s powered with JS or CSS since the URL does not change.

If you need something like that there is a different way of going about it in Hugo.

But again if you value simplicity over URL structure use Hugo taxonomies as they are documented in the Docs.

I’ll probably go for taxonomies, but if I may, can you point me in the direction of how I might otherwise do it in Hugo? This is all a learning process for me

Thank you!