Taxonomies #
Taxonomies let you classify content pages with arbitrary term sets — tags, categories, topics, authors — and then query or group them in templates. When page generation is enabled, Glaze automatically creates a list page and one term page per distinct term value found across all content pages.
Configuring taxonomies #
Define taxonomy keys in glaze.neon. Any key listed here is accepted as a frontmatter field on content pages and indexed during build.
Simple list syntax #
taxonomies:
- tags
- categories
Map syntax #
The map syntax enables per-taxonomy options including automatic page generation:
taxonomies:
tags:
generatePages: true
basePath: /tags
termTemplate: taxonomy/tags-term
listTemplate: taxonomy/tags-list
categories:
generatePages: false
| Option | Default | Description |
|---|---|---|
generatePages |
false |
Auto-generate list and term pages for this taxonomy |
basePath |
/{name} |
URL prefix for generated pages (e.g. /tags) |
termTemplate |
taxonomy/term |
Sugar template for individual term pages |
listTemplate |
taxonomy/list |
Sugar template for the taxonomy list (all terms) page |
A bare key with no options (categories: {}) is equivalent to generatePages: false. Both syntax styles may be mixed in the same config.
Assigning terms in frontmatter #
Use the taxonomy key as a frontmatter field and provide a list of term values:
---
title: My post
tags:
- php
- tutorial
categories:
- web
---
Terms are lowercased and slugified when used in generated URLs (e.g. PHP 8 becomes php-8), but the raw value is preserved in the term metadata field available inside generated templates.
Querying taxonomies in templates #
Taxonomy data is available through $this (the SiteContext) in Sugar templates.
$this->taxonomy(string $name) #
Returns a TaxonomyCollection — an iterable, countable map of term name to PageCollection.
$this->taxonomy('tags')->terms() // ['php', 'tutorial', ...]
$this->taxonomy('tags')->hasTerm('php') // bool
$this->taxonomy('tags')->term('php') // PageCollection
$this->taxonomy('tags')->count() // number of distinct terms
Iterate a TaxonomyCollection to render a tag cloud, archive list, or full term index:
<ul>
<template s:foreach="$this->taxonomy('tags') as $term => $pages">
<li>
<a href="/tags/<?= $term ?>/"><?= $term ?></a>
<span class="badge badge-sm"><?= count($pages) ?></span>
</li>
</template>
</ul>
$this->taxonomyTerm(string $name, string $term) #
Returns a PageCollection of pages tagged with a specific term:
<ul>
<li s:foreach="$this->taxonomyTerm('tags', 'php') as $post">
<a href="<?= $post->urlPath ?>"><?= $post->title ?></a>
</li>
</ul>
Auto-generated pages #
When generatePages: true is set on a taxonomy, Glaze automatically generates a set of pages during build and serves them in the development server:
| URL | Template (default) | Description |
|---|---|---|
{basePath}/ |
taxonomy/list |
All distinct terms with their page counts |
{basePath}/{term}/ |
taxonomy/term |
Pages tagged with that term |
Generated pages are marked as unlisted so they are excluded from regularPages() and do not appear in section navigation. They are still rendered and accessible by URL — direct links work normally.
Term page template #
Create the file at the path matching termTemplate (relative to templates/, default: templates/taxonomy/term.sugar.php). The following metadata is available via $page->meta(...):
| Key | Type | Description |
|---|---|---|
taxonomy |
string |
Taxonomy name, e.g. tags |
term |
string |
Raw term value, e.g. PHP 8 |
<h1>Posts tagged: <?= $page->meta('term') ?></h1>
<ul>
<li s:foreach="$this->taxonomyTerm($page->meta('taxonomy'), $page->meta('term')) as $post">
<a href="<?= $post->urlPath ?>"><?= $post->title ?></a>
</li>
</ul>
List page template #
Create the file at the path matching listTemplate (relative to templates/, default: templates/taxonomy/list.sugar.php). The following metadata is available via $page->meta(...):
| Key | Type | Description |
|---|---|---|
taxonomy |
string |
Taxonomy name, e.g. tags |
<h1><?= ucfirst($page->meta('taxonomy')) ?></h1>
<ul>
<template s:foreach="$this->taxonomy($page->meta('taxonomy')) as $term => $pages">
<li>
<a href="<?= $page->urlPath ?><?= $term ?>/"><?= $term ?></a>
<span class="badge badge-sm"><?= count($pages) ?></span>
</li>
</template>
</ul>
Example #
Given this config:
taxonomies:
tags:
generatePages: true
termTemplate: taxonomy/tags-term
listTemplate: taxonomy/tags-list
With one page tagged php and tutorial, Glaze produces:
| URL | Template |
|---|---|
/tags/ |
templates/taxonomy/tags-list.sugar.php |
/tags/php/ |
templates/taxonomy/tags-term.sugar.php |
/tags/tutorial/ |
templates/taxonomy/tags-term.sugar.php |
Required template directory layout:
templates/
taxonomy/
tags-list.sugar.php
tags-term.sugar.php
Taxonomies and i18n #
When i18n is enabled, taxonomy pages generated via generatePages: true are automatically scoped per language. Glaze generates a separate set of list and term pages for each language, prefixed with the language URL prefix.
For a site with en (default, no prefix) and nl (prefix /nl) and a tags taxonomy:
| URL | Language | Template |
|---|---|---|
/tags/ |
en |
taxonomy/tags-list |
/tags/php/ |
en |
taxonomy/tags-term |
/nl/tags/ |
nl |
taxonomy/tags-list |
/nl/tags/php/ |
nl |
taxonomy/tags-term |
Each generated page carries the correct language code, so $page->language reflects the language of that taxonomy page. Taxonomy queries inside templates (e.g. $this->taxonomyTerm(...)) are also scoped to the current language’s pages.