Examples

Taxonomies

Taxonomies organize content into groups like tags, categories, or authors.

Configuration

Define taxonomies in config.toml:

[[taxonomies]]
name = "tags"
feed = true
paginate_by = 10

[[taxonomies]]
name = "categories"
feed = true

[[taxonomies]]
name = "authors"
Key Type Default Description
name string Taxonomy name (used in front matter)
feed bool false Generate RSS feed for each term
sitemap bool true Include taxonomy pages in sitemap
paginate_by int Items per page on term pages

Using Taxonomies

Assign terms in front matter:

+++
title = "My Post"
tags = ["crystal", "tutorial"]
categories = ["Programming"]
authors = ["Alice"]
+++

A Zola-style [taxonomies] table works too (both spellings are equivalent; an explicit top-level key wins if both are present):

+++
title = "My Post"
[taxonomies]
tags = ["crystal", "tutorial"]
tech = ["crystal", "security"]
+++

In templates, a page's own terms are available as page.taxonomies.<name> (e.g. {% for t in page.taxonomies.tech %}) — also on the page objects inside section.pages, site.pages, and term page lists.

Generated URLs

For a taxonomy named tags with term crystal:

URL Content
/tags/ List of all tags
/tags/crystal/ Pages tagged "crystal"

With paginate_by set, term pages paginate at /tags/crystal/page/2/, /tags/crystal/page/3/, … (page 1 stays at /tags/crystal/). The pager object is described in Data Model › Paginator.

Templates

Both templates receive a ready-made listing as {{ content }} — the term list in taxonomy.html, the page list in taxonomy_term.html. For custom markup, use get_taxonomy() instead of content.

Taxonomy Index

templates/taxonomy.html — List of all terms:

{% extends "base.html" %}

{% block content %}
<h1>{{ page.title }}</h1>
{{ content }}
{% endblock %}

Custom term list:

{% set tax = get_taxonomy(kind=taxonomy_name) %}
<ul>
{% for term in tax.items %}
  <li>
    <a href="{{ get_taxonomy_url(kind=taxonomy_name, term=term.name) }}">
      {{ term.name }} ({{ term.count }})
    </a>
  </li>
{% endfor %}
</ul>

Taxonomy Term

templates/taxonomy_term.html — Pages for a specific term:

{% extends "base.html" %}

{% block content %}
<h1>{{ taxonomy_name }}: {{ taxonomy_term }}</h1>
{{ content }}
{% endblock %}

Custom page list — look up the current term's pages via get_taxonomy():

{% set tax = get_taxonomy(kind=taxonomy_name) %}
{% for term in tax.items if term.name == taxonomy_term %}
<ul>
{% for p in term.pages %}
  <li><a href="{{ p.url }}">{{ p.title }}</a></li>
{% endfor %}
</ul>
{% endfor %}

Template Variables

Available in both taxonomy.html and taxonomy_term.html:

Variable Type Description
taxonomy_name String Taxonomy name ("tags")
taxonomy_term String Current term name (empty on the index page)
content String Pre-rendered listing HTML (terms or pages)

Term Object

Property Type Description
name String Term name
slug String URL-safe name
pages Array<Page> Pages with this term
count Int Number of pages

get_taxonomy() Function

Access taxonomy data anywhere:

{% set tags = get_taxonomy(kind="tags") %}
{% if tags %}
<div class="tag-cloud">
{% for term in tags.items %}
  <a href="/tags/{{ term.slug }}/">{{ term.name }}</a>
{% endfor %}
</div>
{% endif %}

get_taxonomy_url() Function

Generate taxonomy term URL:

<a href="{{ get_taxonomy_url(kind='tags', term='crystal') }}">
  Crystal articles
</a>

Common Patterns

Tag Cloud

{% set tags = get_taxonomy(kind="tags") %}
<div class="tags">
{% for term in tags.items %}
  <a href="/tags/{{ term.slug }}/" 
     class="tag count-{{ term.count }}">
    {{ term.name }}
  </a>
{% endfor %}
</div>

Display Page Tags

{% if page.tags %}
<div class="post-tags">
{% for tag in page.tags %}
  <a href="/tags/{{ tag | slugify }}/">{{ tag }}</a>
{% endfor %}
</div>
{% endif %}

Category Navigation

{% set categories = get_taxonomy(kind="categories") %}
<nav class="categories">
{% for cat in categories.items %}
  <a href="/categories/{{ cat.slug }}/">
    {{ cat.name }} ({{ cat.count }})
  </a>
{% endfor %}
</nav>

See Also