Iterators
Iterators are a special mechanism in Toucan used to implement pagination. They allow you to split query results across multiple pages by automatically generating content bundles — one for each page — prior to rendering.
When defined in a pipeline, iterators run before other content is processed. Each iterator creates a virtual content bundle for every page in the result set. These bundles can then be styled and rendered just like regular content.
Definition
Iterators are configured under the iterators
key in a render pipeline. Each entry requires a unique identifier (the iterator key) and an associated query definition.
iterators:
<iterator_key>: <query>
Here’s a real example from this site:
iterators:
post.pagination:
contentType: post
scope: detail
limit: 12
orderBy:
- key: publication
direction: desc
In this example, Toucan will paginate over all post items, 12 per page, sorted by the publication date in descending order. Each page of the result will generate a separate content bundle that you can render with its own template.
If you’re not familiar with query definitions, review the Queries documentation first.
Iterator bundle
To render the paginated output, you need to create a content bundle that references the iterator. This is done by using the iterator’s identifier enclosed in double curly braces as the filename or slug:
{{iterator_id}}
For instance, the post.pagination
iterator would correspond to {{post.pagination}}
.
You typically use a page type content bundle with a dedicated template. You can include special placeholders in the front matter — such as {{number}}
and {{total}}
— to refer to the current page number and the total number of pages, respectively.
Example bundle:
---
type: page
home: articles/page
slug: articles/page/{{post.pagination}}
title: "Latest news, page {{number}} of {{total}}"
description: "Stay updated with the latest news and updates. Page {{number}} of {{total}}."
template: blog.posts
---
Articles
Browse all articles.
The Markdown content defined in this bundle will be rendered for each page generated by the iterator.
Output Structure
After the site is rendered, the output folder will contain one directory per page, each with its own index.html:
articles
└── page
├── 1
│ └── index.html
└── 2
└── index.html
Each folder corresponds to one page in the paginated result. Toucan automatically replaces {{post.pagination}}
in the slug with the current page number during generation.
Troubleshooting
It’s common to omit the type field in content bundles, and in most cases, this is perfectly fine. Toucan will infer the content type based on the file path using the paths
defined in your content type configuration:
---
title: "..."
description: "..."
...
---
id: post
paths:
- blog/posts
However, iterator bundles are generated dynamically and are often placed alongside other content files that do use these predefined paths. In such cases, if you don’t explicitly set the type in the front matter, Toucan may incorrectly assign the type based on the surrounding file structure — leading to unexpected rendering behavior or the wrong template being used.
To avoid this, always define the type explicitly in iterator bundles:
---
type: page
---
This ensures the correct template is applied and avoids accidental inheritance of unrelated paths from other content types.