Organize section content under nested taxonomy

I have a rather simple use case where I want to build a product catalogue that are ordered into categories and subcategories.
Here is an example of the categories hierarchy :
– category1
---- subcategory A
---- subcategory B
– category2
---- subcategory C
---- subcategory D

And I have a few products, say “Product 1”, “Product 2” and “Product 3” that each belong to a different product category. However I cannot find a way to say that, for example, “Product 1” belongs to “subcategory A”. It works well with first level categories but not with nested levels.

Notes :

  • My products are just readme files into a “product” section
  • Each product has one category (the actual Hugo category taxonomy) declared in Front Matter such as " categories:["subcategory A"]"

Is there any simple way to achieve what I’m trying to do, or am I totally mistaken ?

1 Like

It’s virtually impossible to assign content to Nested Sections with Taxonomies.

A Nested Taxonomy residing under a Section does not know that it is nested. Hugo still considers it as a Top Level Taxonomy.

This is something that I would also like to see in Hugo someday.

CC/ @Mikhail @orevial

Ok! I retract the above comment. It’s possible to have a Multi-level taxonomy or a Nested Taxonomy under a Section with Hugo, but it’s not simple at all.

The trick lies in setting the Taxonomy permalinks to use :slug in the config

Then in content files one can specify the Taxonomy PATH like so:
taxonomy = "/section/nested-section/term"

And then to render links to the Taxonomy pages one can roughly do it like so:

{{- $var := .Scratch -}}
{{ range where .Site.AllPages "Section" "taxonomy-name" }}
{{- $var.Add "taxa" (slice .RelPermalink) -}}
{{ end }}

Store the relative permalink of the taxonomy lists in a variable with .Scratch

And then manipulate that relative permalink string with RegEx to generate the link’s anchor text and if needed the link to the ancestors of the Nested Taxonomy.

(I am not going to go into the RegEx specifics here -I will not spoon feed the code-).

And basically that’s roughly how I did it.

It took me about 2 fun weeks of trial and error to achieve the above. But it’s possible to do this in Hugo today.

P.S. I still hope that at some point it will be possible to have Nested (or Multi-level) Taxonomies in Hugo without having to resort to the brute force of .Scratch, replaceRE etc.


Thanks @alexandros for your input, I’ll definitely have a look at the solution/workaround you are suggesting.
However I ended up doing another workaround using some “virtual” taxonomy, I mean by that that I set up a second taxonomy that is used in the front matter of my content but this taxonomy itself is never displayed :

  • default “categories” taxonomy is used to display the actual content of the categories, in my case my products
  • “productcategories” taxonomy is used to map the product to the actual category it refers to in the layout

So assuming that I want Product 1 to appear under subcategory A, I will first define my virtual taxonomy in Product 1 content :
productcategories: ["subcategory A"]

Now to be able to display the correct products on each of my categories, I’ve defined the following on the list.html layout of the categories taxonomy :

        {{ $productcategory := .Title }}
        {{ if isset .Params "productcategory" }}
        {{ $productcategory := .Params.productcategory }}
        {{ end }}

        {{ range $key, $value := .Site.Taxonomies.productcategories }}
		{{ if eq $key $productcategory }}
			{{ range $value.Pages }}
				<li class="product">
				    Product content appears here...
			{{ end }}
		{{ end }}
       {{ end }}

Note : I didn’t need this on the product page because I simply don’t need to display category info when displaying a product, but I could have easily done the same thing on the product layout page !

I published a repository with the technique I use to achieve Nested Taxonomies with Hugo.


There are taxonomies for Chronological Blog Archives and posts grouped by Color.

1 Like

This repository is not exist.

Hi, I posted the above link 2 years ago. Sometime later I unpublished the repo for unrelated reasons.

Unfortunately I currently do not have the time to upload another sample repo.
Maybe some time in the future.