Taxonomies & Terms

Group nodes by category, tag, or anything custom — in any language.

Taxonomies vs terms

A taxonomy is the bucket type — Category, Tag, Cuisine, Difficulty. A term is an instance inside that bucket — Italian in Cuisine, Easy in Difficulty. Same model as WordPress.

Taxonomies are attached to one or more node types: the same Tag taxonomy can apply to blog_post, recipe, portfolio_entry at once.

Manage taxonomies at /admin/taxonomies

List, create, edit, delete. Per taxonomy you set:

  • Slug — lowercase, immutable after creation
  • Label / Label plural
  • Hierarchical — boolean. true for category-style nesting, false for flat tag-style
  • Attached node types — multi-select of node-type slugs that should expose this taxonomy
  • Term field schema — custom fields per term (see Custom Fields). Lets you decorate terms with images, descriptions, color tags, anything

Manage terms

Terms are scoped per node type + taxonomy + language. Open a node-type list page (e.g. /admin/nodes/recipe) and use the Taxonomies tab to manage terms for that type, or browse the dedicated terms screens via the sidebar.

Per-term fields

  • Slug — auto-generated from name, editable
  • Name
  • Parent — only if the taxonomy is hierarchical
  • Description
  • Custom field values from the term schema

Reorder & nest

Drag rows to reorder. For hierarchical taxonomies, drag onto another row to nest.

Per-language with linked translations

Terms are per-language. Slug uniqueness is scoped to (node_type, taxonomy, slug, language_code) — so you can have cuisine/italian in English and cuisine/talianska in Slovak, both pointing at the same logical term.

Linking is done via translation_group_id. Translate an existing term:

REST
POST /admin/api/terms/<id>/translations
Content-Type: application/json

{ "language_code": "sk" }

The source row gets a fresh translation_group_id if it didn't already have one; the clone joins the same group with the new language. The admin UI exposes this through the term editor's Translations tab — you don't normally call the route directly.

HEADS UP
When a node references a term via a term-typed custom field, store the value as {slug, name}, not a bare slug string. The admin's term-field component requires the object form to pre-select. Templates accept either shape on render.

Attaching terms to a node

On the node edit screen, every taxonomy attached to that node type renders as a multi-select in the sidebar. Selecting a term stores it in taxonomies.<taxonomy_slug> as an array of {slug, name} objects.

node.taxonomies
{
  "category": [{ "slug": "engineering", "name": "Engineering" }],
  "tag":      [
    { "slug": "go",  "name": "Go" },
    { "slug": "cms", "name": "CMS" }
  ]
}