Taxonomies let you classify content with terms like tags, categories, or any custom grouping. Zorto auto-generates listing pages for each taxonomy and its terms.

Defining taxonomies #

Taxonomies are declared in config.toml with [[taxonomies]]:

[[taxonomies]]
name = "tags"

[[taxonomies]]
name = "categories"

Each entry requires a name field. The name determines the URL path (/tags/, /categories/) and the frontmatter field name.

Note

If you omit [[taxonomies]] entirely, Zorto creates a default tags taxonomy. Once you define any [[taxonomies]] entry, only the ones you list are active.

Assigning terms #

In page frontmatter, add a top-level array field matching the taxonomy name:

+++
title = "Building a web app with Rust"
date = "2026-03-15"
tags = ["rust", "web", "tutorial"]
categories = ["engineering"]
+++

Any top-level frontmatter key whose value is an array of strings is treated as a taxonomy assignment. The key must match a taxonomy name defined in config.toml.

Auto-generated pages #

For each taxonomy, Zorto generates two types of pages:

List page #

A page at /<taxonomy>/ showing all terms. For tags, this renders at /tags/.

Template: <taxonomy>/list.html (e.g. tags/list.html)

Context variables:

VariableTypeDescription
termsarray of objectsAll terms in this taxonomy, sorted alphabetically
terms[].namestringOriginal term name (e.g. "Rust")
terms[].slugstringURL-safe slug (e.g. "rust")
terms[].permalinkstringFull URL to the term page
terms[].pagesarrayPages with this term, sorted by date (newest first)
configobjectSite configuration

Term page #

A page at /<taxonomy>/<term>/ showing pages with that term. For the tag "rust", this renders at /tags/rust/.

Template: <taxonomy>/single.html (e.g. tags/single.html)

Context variables:

VariableTypeDescription
termobjectThe current taxonomy term
term.namestringOriginal term name
term.slugstringURL-safe slug
term.permalinkstringFull URL to this term page
term.pagesarrayPages with this term, sorted by date (newest first)
configobjectSite configuration

Template examples #

Taxonomy list template #

Create templates/tags/list.html to render the tags index page:

{% extends "base.html" %}

{% block content %}
<h1>Tags</h1>

<ul>
{% for term in terms %}
  <li>
    <a href="{{ term.permalink }}">{{ term.name }}</a>
    ({{ term.pages | length }} post{{ term.pages | length | pluralize }})
  </li>
{% endfor %}
</ul>
{% endblock %}

Taxonomy single template #

Create templates/tags/single.html to render a page for each tag:

{% extends "base.html" %}

{% block content %}
<h1>Posts tagged "{{ term.name }}"</h1>

{% for page in term.pages %}
<article>
  <h2><a href="{{ page.permalink }}">{{ page.title }}</a></h2>
  {% if page.date %}
    <time>{{ page.date | date(format="%B %d, %Y") }}</time>
  {% endif %}
  {% if page.summary %}
    {{ page.summary | safe }}
  {% endif %}
</article>
{% endfor %}
{% endblock %}

Linking to taxonomy terms from pages #

Use get_taxonomy_url in any template to generate a link to a term page:

{% if page.taxonomies.tags %}
<div class="tags">
  {% for tag in page.taxonomies.tags %}
    <a href="{{ get_taxonomy_url(kind="tags", name=tag) }}">
      {{ tag }}
    </a>
  {% endfor %}
</div>
{% endif %}

Template directory structure #

Taxonomy templates live in a subdirectory named after the taxonomy:

📂templates/
├── 📝base.html
├── 📝page.html
├── 📝section.html
├── 📂tags/
    ├── 📝list.htmlrenders /tags/
    ├── 📝single.htmlrenders /tags/rust/, etc.
├── 📂categories/
    ├── 📝list.htmlrenders /categories/
    ├── 📝single.htmlrenders /categories/engineering/, etc.

Each taxonomy gets its own template directory.

Warning

Taxonomy pages are only rendered if the corresponding template exists. If there is no tags/list.html, the /tags/ page will not be generated.

Multiple taxonomies #

You can define as many taxonomies as needed:

[[taxonomies]]
name = "tags"

[[taxonomies]]
name = "categories"

[[taxonomies]]
name = "authors"

Each taxonomy is completely independent. A page can have terms in any or all of them:

+++
title = "Zorto 1.0 release"
tags = ["release", "rust"]
categories = ["announcements"]
authors = ["cody"]
+++

Term slugification #

Term names are slugified for URLs: spaces become hyphens, special characters are removed, and the result is lowercased. For example:

Term nameSlugURL
"Rust"rust/tags/rust/
"My Tag"my-tag/tags/my-tag/
"C++"c/tags/c/

Pages within each term are sorted by date in reverse chronological order (newest first). Terms in the list page are sorted alphabetically by name.

Further reading #