Problem statement
I want to implement two features for my tag = "tags"
taxonomy, inspired by software like Hydrus Network or TagStudio:
- Tag aliases, or canonical/sibling tags. For example, if I tag something as
yugioh
,yu-gi-oh
, orygo
, loading the term list page for any of these will return content tagged with any of these. One of these can be declared canonical, e.g.yu-gi-oh
, and in this case,yugioh
andygo
should/could be normalized toyu-gi-oh
. At the very least,/tags/yugioh/
should either return that tagged content, or otherwise redirect to/tags/yu-gi-oh/
instead. - Tag composition, or hierarchical/parent tags. For example, if I tag something as
yugi muto
, this logically implies the tagyu-gi-oh (duel monsters)
, which in turn logically implies the tagyu-gi-oh
.
For the latter, I found Hierarchical Tags in Hugo which I intend to look at later, but for now I wanted to start with the former.
What I’ve tried
Preamble: content adapters and site data
I vaguely intend to do this with content adapters and some site data in data/tags/
, since this would allow me to use that data for other things, and it would save me from polluting my content directory.
I take the following data from data/tags/yugioh.json
:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"@base": "https://trwnh.com/tags/"
}
],
"id": "yu-gi-oh",
"name": "Yu-Gi-Oh!",
"summary": "A media franchise including several series mostly revolving around the fictional card game of Duel Monsters.",
"alsoKnownAs": ["yugioh", "yu-gi-oh!", "ygo"]
}
I use the following content/tags/_content.gotmpl
file:
{{ $data := .Site.Data.tags }}
{{ range $data }}
{{ $title := .name }}
{{ $summary := .summary }}
{{ $aliases := .alsoKnownAs }}
{{ $page := dict
"title" $title
"summary" $summary
"aliases" $aliases
"path" .id
"kind" "term"
}}
{{ $.AddPage $page }}
{{ end }}
By my understanding, this should be equivalent to creating a tag page at content/tags/yu-gi-oh/_index.md
with the following frontmatter:
title = "Yu-Gi-Oh!"
summary = "A media franchise including several series mostly revolving around the fictional card game of Duel Monsters."
aliases = [
"ygo",
"yugioh",
"yu-gi-oh!"
]
It is rendered by the template at layouts/_default/term.html
:
{{ define "body" }}
{{ $tagSet := slice .Name | append .Aliases }}
{{ $pages := where .Site.RegularPages "Params.tags" "intersect" $tagSet }}
<body class="layout-_default-term">
<main id="main">
<h1>Tag title: {{.Title}}</h1>
<p>Summary: {{.Summary}}</p>
{{ range $pages }}
<li><a href="{{ .Permalink }}">{{ .Permalink }}</a></li>
{{ end }}
{{ range .Aliases }}
<p>{{.}}</p>
{{ end }}
</main>
</body>
{{ end }}
Using tag aliases
Given content/foo.md
with the following frontmatter:
tags = ["ygo"]
Given content/bar.md
with the following frontmatter:
tags = ["yugioh"]
The intended result is to:
- have
/tags/yu-gi-oh/
list both pages - have
/tags/ygo/
list both pages, or redirect to/tags/yu-gi-oh/
- have
/tags/yugioh/
list both pages, or redirect to/tags/yu-gi-oh/
- have
/tags/yu-gi-oh!/
list both pages, or redirect to/tags/yu-gi-oh/
The actual result is:
/tags/yu-gi-oh/
lists both pages as expected/tags/ygo/
only lists/foo/
, and is not recognized as an alias (because it was overridden by the page generated from the frontmatter incontent/foo.md
)/tags/yugioh/
only lists/bar/
, and is not recognized as an alias (because it was overridden by the page generated from the frontmatter incontent/bar.md
)/tags/yu-gi-oh!/
redirect to/tags/yu-gi-oh/
as expected
Where to go from here
The question is: am I on the wrong track, and if so, what is the right track? I understand that aliases
will generally be overridden when actual content pages exist, but I want to bypass this behavior somehow.