Content Management

Content types


A content type acts as a skeleton for your content. A site can have several content types. For example, a blog might use content types for posts, authors, and tags.

You define custom content types in the types folder using simple YAML files.

Basics

Here’s an example content type that defines a blog post, we’re going to explain the properties relations and queries, later on:

id: post
default: false
paths:
    - blog/posts

properties:
    # list of properties

relations:
    # list of relations

queries:
    # list of queries    

The YAML file defines a content type with the following structure:

  • id: A unique identifier for the content type (for example, post).
  • default: Marks this as the default content type if set to true. Only one content type can be set as the default. If you mark a type as default: true, it will be the fallback for any content that doesn’t match other types. This helps Toucan know which structure to use when there’s ambiguity.
  • paths: The list of file paths, where this type of contents are stored, Toucan will automatically match files in these locations to this content type.
  • properties: Lists the fields for this content type.
  • relations: Describes the connections with other content types.
  • queries: Specifies any additional objects to be queried for this content type.

When you create new content, the content type acts as its backbone. Each content type sets its own properties, relationships, and queries. The path and id help locate and identify each piece of content, making it easier to form relationships and query additional objects for every item.

Properties

For example, a blog post might include a title, description, image, publication date, and a flag to mark the article as featured. Here’s how you can represent these fields using the content type definition YAML file:

properties:
    title:
        type: string
        required: true
    description:
        type: string
        required: true
    image:
        type: asset
        required: true
    publication:
        type: date
        config: 
            format: "yyyy-MM-dd HH:mm:ss"
            locale: en-US
            timeZone: EST
        required: true
    featured:
        type: bool
        required: false
        default: false

Each property defined in this section will be validated against the content’s front matter. If a property is marked as required, Toucan will warn you if it’s missing or invalid. Properties can also be used to query your content.

Relations

Relations in Toucan are always one-way. They let you link your content types by defining how one type connects to another. This approach helps you organize your data and create clear, meaningful connections between different pieces of content.

For example, a blog post can have one or more authors or tags. You can define a separate author type and a tag type, then create relationships between the post, author, and tag using the relations section like this:

relations:
    authors:
        references: author
        type: many
        order:
            key: title
            direction: asc
    tags:
        references: tag
        type: many
        order:
            key: title
            direction: asc

The reference key is the identifier for the related content type. The type shows if the association is one or many. You can also set a custom order for each field by giving a key and a direction.

Example content

Here is an example of what a content markdown file for a blog post might look like, based on the properties and relations we described earlier:

---
type: post
title: "Example post title"
description: "Example post description"
publication: "2024-12-15 00:00:00"
tags: 
    - releases
authors:
    - tibor-bodecs
# featured: true
---

# This is an example

Just an example blog post.

The front matter keys must match the property names defined in the content type. All values should be valid. The “featured” field is optional and will default to false if not set. All other fields are required because they use the “required” property in the example definition. Toucan will parse every piece of content and validate it against your content types. This helps you keep your content consistent and well-structured.

Queries

Since relations in Toucan are always one-way, you cannot automatically access related objects in both directions. Queries solve this problem by letting you fetch related items from the opposite direction.

For example, if a post references an author, you can use a query on the author type to get all posts written by that author. This makes it easy to display collections of related content, even when the relationship is only defined in one place.

id: author
path:
    - authors

properties:
    name:
        type: string
        required: true

queries:
    posts:
        contentType: post
        filter:
            key: authors
            operator: contains
            value: "{{id}}"
        orderBy:
            - key: publication
              direction: desc

In the example above:

  • The path defines where author content is located.
  • The queries section sets up a posts query that:
    • Pulls content of type post
    • Filters posts that include the current author’s ID in their authors field
    • Sorts results by the publication date in descending order

This query runs automatically when rendering a single author page. The result is accessible in templates via the {{posts}} variable.

To make the query work, the post type must define a matching relation:

id: post
paths:
    - posts

properties:
    title:
        type: string
        required: true
    publication:
        type: date
        
        required: true
    featured:
        type: bool
        required: false
        default: false

relations:
    authors:
        references: author
        type: many
        order:
            key: name
            direction: asc

In the snippet above:

  • relations defines connections between content types
  • authors is the name of the relation field for this content type
  • references: author specifies the target content type this relation points to
  • type: many means a post can be linked to multiple authors
  • order controls how the related author entries are sorted in templates

Relation fields appear in front matter as string references. In templates, they resolve to full objects.
For example, {{authors}} will contain author objects sorted by name.

You always define your relations using the front matter, but you never reference queries within your content. Queries are not included in the content itself; instead, they provide context variables when rendering your template files. This means that while relations help link content items together, queries allow you to fetch and display related data dynamically in your templates, giving you more flexibility and control over how your content appears on the site.

That’s how content types work in Toucan.

Reference

Properties

Property types

The following property types are available:

bool – A boolean value.

Represents a true or false value.

int – An integer number.

Represents whole numbers such as 1, 0, or -5.

double – A floating-point number.

Represents decimal numbers like 3.14 or -0.75.

string – A string value.

Represents a sequence of characters, such as "Hello" or "123".

asset – Asset reference stored as a string value.

Represents an asset from the content’s assets folder. The value of this property will be resolved to a full path when rendering the contents.

Example:

type: asset
date – A date value with optional configuration.

Represents a date with an optional custom configuration. Optionally to define the format string, locale, and timeZone as a config object.

Example:

type: date
config: 
    format: "ymd"
    locale: en-US
    timeZone: EST
array – A list of typed values.

Represents an array. The of parameter defines the type of its elements.

Example:

type: array
of: 
    type: string

Relations

Relation types

The following relation types are available:

one – A one-to relation type.

Represents a one-ended relation.

e.g. a guide can have one category

category: "getting-started"
many – A many-to relation type.

Represents a many relation.

e.g. a post can have multiple authors.

authors:
    - "john-doe"
    - "jane-doe"

Direction

The following directions values are available:

asc – Ascending

Sorts values in ascending order, from lowest to highest.
For example, A → Z or 1 → 9.

desc – Descending

Sorts values in descending order, from highest to lowest.
For example, Z → A or 9 → 1.

Queries

See the queries guide for more information.