Keeping content generic but style them in on page categories?

I’m trying to figure out the best way to keep my product content files organized on page, meaning when I range through them they are displayed (with a header / view) in an order of categories.

Meaning, I have 9 product.md files, 3 are hair care, 3 are body care, and 3 are nail care. How could I structure my page to look like (with headers):

Hair care

  • List item
  • List item
  • List item

Nail care

  • List item
  • List item
  • List item

Bodycare

  • List item
  • List item
  • List item

The only way I can think of doing it this way is to loop through each category, but I’d like to keep my data dynamic. Is there a way that I can range through all of these and keep them in their categories on page?

Is it required that all the product.md be in the same directory, or are you tied to a single directory and using taxonomies to label them?

You can do this in either scenario, but it depends on your requirements.

I need all the products to be in the same directory for a few reasons mainly I need it a easy generic system. I see how this makes it more difficult.

Can I range multiple taxonomies with a single range and group each one, to have them collected in different containers?

You should be able iterate through taxonomy terms (assuming I’m not confusing taxonomies and term, as I often do) and then the taxonomies within each term, which gets you the categories and the pages in them.

I’ll try to get some time to create and post an example, ‘soon’ (unless someone beats me to it).

content
├── product
│   ├── product-1.md
│   ├── product-2.md
│   ├── product-3.md
│   ├── product-4.md
│   ├── product-5.md
│   ├── product-6.md
│   ├── product-7.md
│   ├── product-8.md
│   └── product-9.md
└── _index.md

layouts/product/list.html

{{ define "main" }}
  <h1>{{ .Title }}</h1>
  {{ .Content }}

  {{ range .Site.Taxonomies.categories }}
    <h2>{{ .Page.Title }}</h2>
    {{ range .Pages }}
      <a href="{{ .Permalink }}">{{ .LinkTitle }}</a><br>
    {{ end }}
  {{ end }}

{{ end }}

Then see http://localhost:1313/product/

See https://gohugo.io/variables/taxonomy/#example-usage-of-sitetaxonomies.

1 Like

Okay that makes sense, just to confirm:

          {{ range $key, $value := $taxonomy }}
          <li> {{ $key }} </li>

Key would be “Nail care” and would group the taxonomies ‘products’ under that list?

@jmooring Silly question, but is there an easy way to use a Param to so that categories is not hard-coded in your example above? (I can open a separate topic if need be).

Key would be “Nail care”

No. $key would be nail-care. That’s why I used .Page.Title.

{{ $foo := "categories"}}
{{ range (index .Site.Taxonomies $foo) }}
  <h2>{{ .Page.Title }}</h2>
  {{ range .Pages }}
    <a href="{{ .Permalink }}">{{ .LinkTitle }}</a><br>
  {{ end }}
{{ end }}
1 Like

Works perfectly, one last follow up question, how would you apply weights to this? (show first to last categories by specified weight or any other way of organizing)

Take a look at

It also depends on whether you want to sort the terms (e.g. the different categories) or the taxonomies themselves, or the pages with a term (e.g. ‘nail-care’ pages).

I’m specifically talking about the categories [nail-care, hair-care], I don’t see how I can set a weight with the WeightedPages how do I set those? Is that in the config?

The “tags_weight = 22” is totally confusing.

Hmmm…I don’t know if you can sort terms (nail-care, hair-care, body-care) by a weight.

Taxonomies can be ordered by either alphabetical key or by the number of content pieces assigned to that key.

From Taxonomy templates | Hugo.

I think you could create a separate slice (slice “body-care” “nail-care” “hair-care”) and range on that slice as follows:

{{ $curPage := . }}
{{ $productTypeOrder := (slice "body-care" "nail-care" "hair-care") }}
{{ range $productTypeOrder }}
    {{ range (index site.Taxonomies.categories .) }}
        <h2>{{ .Page.Title }}</h2>
        {{ range .Pages }}
            <a href="{{ .Permalink }}">{{ .LinkTitle }}</a><br>
        {{ end }}
    {{ end }}
{{ end }}

@jmooring does that make sense, and even if it works, is there a better way?

I don’t think .Page.Title is right in the above.

To clarify, you would like the ability to specify an arbitrary order—not alphabetical, and not based on the number of pages associated with a particular term.

Please confirm.

Yes, I would like to display the “categories” by what I specify should be seen first.

layouts/_default/list.html

{{ define "main" }}
  <h1>{{ .Title }}</h1>
  {{ .Content }}

  {{ range (sort .Site.Taxonomies.categories ".Page.Weight") }}
    <h2>{{ .Page.Title }}</h2>
    {{ range .Pages }}
      <a href="{{ .Permalink }}">{{ .LinkTitle }}</a><br>
    {{ end }}
  {{ end }}

{{ end }}

Create term section pages:

hugo new categories/bodycare/_index.md
hugo new categories/nail-care/_index.md
hugo new categories/hair-care/_index.md

In each of the term section pages, set weight in the front matter. For example:
content/categories/bodycare/_index.md

+++
title = "Bodycare"
date = 2021-03-20T12:59:03-07:00
draft = false
weight = 20
+++

Weights can be positive or negative, but not zero. Lighter values float to the top, while heavier items sink to the bottom.

I’m sorry ONE last question, I’m trying to access my data from the range, but it seems it’s only the on page data since we’re parsing the tags / categories.

How would I be able to return my content file with the range? I don’t see the data with .Page.Data either.

    {{ range .Site.Taxonomies.tags  }}
    {{ .Page }}

Page(/tags/barbering) Page(/tags/color) Page(/tags/haircuts) Page(/tags/makeup) Page(/tags/styling)

Content a product page:
e.g., content/product/product-1.md

Or content from a term page:
e.g., content/categories/bodycare/_index.md

Which one?

Remember, in the example above we are looping through both.

This.

Sorry I don’t see how we’re looping through both unless you mean with the slice.

This is the last example I provided. There’s no slice.

{{ define "main" }}
  <h1>{{ .Title }}</h1>
  {{ .Content }}

  {{ range (sort .Site.Taxonomies.categories ".Page.Weight") }}
    <h2>{{ .Page.Title }}</h2>
    {{ range .Pages }}
      <a href="{{ .Permalink }}">{{ .LinkTitle }}</a><br>
    {{ end }}
  {{ end }}

{{ end }}

The outer loop (terms) is:
{{ range (sort .Site.Taxonomies.categories ".Page.Weight") }}

The inner loop (products) is:
{{ range .Pages }}

You want to place {{ .Content }} within the inner loop.