Docs › Collections
Collections
Collections define structured content types with custom fields, card templates for list views, and detail templates for individual items. Common examples include blogs, projects, portfolios, and event listings.
Creating a collection
Go to Collections → New collection:
- Name — Display name (e.g. "Blog")
- Slug — URL prefix (e.g.
blogserves items at/blog/{item-slug}) - Description — Optional
- Fields schema — JSON array defining custom fields
- Card template — Jinja2 HTML for list/feed views
- Detail template — Jinja2 HTML for the full item page
- Empty template — HTML shown when the collection has no published items
- Items per page — Pagination size for feeds (default: 10)
Fields schema
Define custom fields as a JSON array:
[
{ "name": "summary", "type": "text", "required": true },
{ "name": "body", "type": "html", "required": true },
{ "name": "tags", "type": "text", "required": false }
]
These fields appear in the item editor and are stored as JSON. Access them in templates via {{ item.field_name }}.
Card template
The card template renders each item in a feed. It receives an item object with all fields:
<article>
<h3><a href="/blog/{{ item.slug }}">{{ item.title }}</a></h3>
<p>{{ item.summary }}</p>
</article>
Detail template
The detail template renders a single item page. It also receives the item object:
<article>
<h1>{{ item.title }}</h1>
{{ item.body }}
</article>
If no detail template is set, a default <h1> + body layout is used.
Embedding feeds in pages
Use the <CollectionFeed> JinjaX component in any page body:
<CollectionFeed slug="blog" />
This renders the collection's card template for each published item with HTMX-powered "Load more" pagination.
Slug history
When you rename a collection item's slug, the old slug is recorded. Requests to the old URL automatically redirect (301) to the new one.
Item ordering
Items are ordered by sort_order. Use the arrow buttons in the items list to reorder them. You can also mark items as Featured for use in custom template logic.