HUGO

Using taxonomies metadata in list and single templates

I’m not familiar with Hugo data model and can’t find a working detailed tutorial (or just example site) on using additional taxonomies metadata in templates. That’s why question is probably silly.

Regular page front matter:

authors: "william-thackeray"

/content/authors/william-thackeray/_index.md

fullname: "William Makepeace Thackeray"

list.html

<div class="meta-name">
  {{ $tagsLen := len .Params.authors }}
  {{ if gt $tagsLen 0 }}
      {{ range .Params.authors }}
      {{ . }}
      {{ end }}
  {{ end }}
</div>

as expected I see william-thackeray

The question is: what should be instead of dot (.) to output author’s fullname?

<div class="meta-name">
  {{ $tagsLen := len .Params.authors }}
  {{ if gt $tagsLen 0 }}
    {{ range .Params.authors }}
      {{ (site.GetPage (printf "authors/%s" .)).Params.fullname }}
    {{ end }}
  {{ end }}
</div>
1 Like

It works. Thank you! So specific taxonomy metadata access performed via Page object with special name %taxonomy_plural%/%term%
The only tip I’ve already bumped up is that front matter in yaml

---
authors: "william-thackeray"
---

leads to error “can’t iterate”. To access range iterations it’s necessary to write in list form even with single author:

---
authors:
- william-thackeray
---

In latter case iteration works as intended

Adjacent question arrived. Now my template code for rendering book tags looks like (simplified) this:

{{ range .Params.authors }}
    <a href="{{ printf "authors/%s" . }}">{{ (site.GetPage (printf "authors/%s" .)).Params.fullname }} </a>
{{ end }}

{{ range .Params.booktitles }}
    <a href="{{ printf "booktitles/%s" . }}">{{ (site.GetPage (printf "booktitles/%s" .)).Params.fullname }} </a>
{{ end }}

{{ range .Params.publishers }}
    <a href="{{ printf "publishers/%s" . }}">{{ (site.GetPage (printf "publishers/%s" .)).Params.fullname }} </a>
{{ end }}

It seems there must be a way to reuse anchor generation pattern via partial like

{{ partial render-tag "authors" }}

but I can’t find how to manage partial parameter to use as taxonomy id and as printf pattern (string) in this case. Is it possible?

May be something like

{{ $ctx := .ctx }}
{{$tax := .taxonomy }} 
{{ $string := printf "%s/%s" $tax $ctx }}
<a href="{{$string}}">{{ (site.GetPage($string)).Params.fullname }}</a>

calling it like

{{ partial "render-tag" (dict "ctx" . taxonomy "author") }}

Although I’m not sure that using “%s” to format an author’s full name will result in a valid URL here. E.g. “William Makepeace Thackeray” would result in

<a href="authors/William Makepeace Thackeray">

with unescaped spaces. Maybe urlize helps.

1 Like

There’s nothing special about the name. It’s just the path to the page.

You should always specify taxonomy terms in a slice, even if there is only one.

Good, but there’s a simpler, more defensive way to iterate through the authors. Your empty slice check will throw an error if the page doesn’t contain authors in front matter. You don’t need to check for an empty slice—the range command does that for you.

<div class="meta-name">
  {{ range .Params.authors }}
    {{ (site.GetPage (printf "authors/%s" .)).Params.fullname }}
  {{ end }}
</div>

Yes, and @chrillek has described the concept.

layouts/partials/render-tag.html

{{ $taxonomy := .taxonomy }}
{{ with .ctx }}
  {{ range index .Params $taxonomy }}
    {{ $p := site.GetPage (printf "%s/%s" $taxonomy (urlize .)) }}
    <a href="{{ $p.RelPermalink}}">{{ $p.Params.fullname }}</a>
  {{ end }}
{{ end }}

And call it with:

{{ partial "render-tag.html" (dict "ctx" . "taxonomy" "authors" )}}

Is there a reason that you can’t use the .Title instead of .Params.fullname? I ask because it seem repetitive. Instead of this:

---
title: "William Thackeray"
date: 2021-04-20T07:04:48-07:00
draft: false
fullname: "William Makepeace Thackeray"
---

Why not this?

---
title: "William Makepeace Thackeray"
date: 2021-04-20T07:04:48-07:00
draft: false
---

Then your partial would look like:

{{ $taxonomy := .taxonomy }}
{{ with .ctx }}
  {{ range index .Params $taxonomy }}
    {{ $p := site.GetPage (printf "%s/%s" $taxonomy (urlize .)) }}
    <a href="{{ $p.RelPermalink}}">{{ $p.Title }}</a>
  {{ end }}
{{ end }}

This would reduce data entry and the potential for errors and missing information.

1 Like

One more thought, just in case you were not aware. You can use spaces and capital letters in your terms. For example:

authors:
  - "Michael Moore"
  - "Mandy Patinkin"
booktitles:
  - "Fired"
  - "No Where But Up"
publishers:
  - "Greenway"
  - "Lexington Press"
1 Like

Yes, you’re right. And even quotes are not necessary with this type of front matter. But some books must be with non-ASCII letters (yes, I know, removePathAccents=true) including cyrillic authors, titles and publishers. It’s not convenient to process and send urls like authors/лев-толстой. Hugo AFAIK still has no tools to make cyrillic transliterations like authors/lev-tolstoi and transparently work with them. So, after rigorous brainstorming :slight_smile: I decided to use transliterated URLs as taxonomies with metadata.

Once more - thank you for detailed answers. They really not only helping realise my current humble project, but makes me better understand real power of Hugo.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.