Collections and Pagination

Content Collections and Pagination

Pages can define content collections via a content block in frontmatter. The collection specifies which pages to include, how to filter and sort them, and how many to show per page. The result is exposed as page.collection in the template context, with pagination metadata in page.pagination.

Collection Frontmatter

---
title: Blog
template: blog
content:
  items: "@self.children"        # Source: children of current page
  order:
    by: date                     # Sort field: date, title, order, url
    dir: desc                    # Direction: asc or desc
  limit: 10                     # Items per page (enables pagination)
  filter:
    tags: [rust]                 # Only pages with these tags
    author: "John Doe"           # Only pages by this author
    published: true              # Only published pages (default)
---

The items field currently supports @self.children to collect child pages of the current page.

Sorting

order.by accepts date, title, order, or url, with dir set to asc or desc.

Sorting by date is chronological, not alphabetical: each page’s date is parsed into a calendar date before comparison, so every format Accent accepts sorts in true date order – ISO (2026-06-14, and non-zero-padded forms like 2026-5-24), US (06/14/2026), European (14.06.2026), and long or short month (June 14, 2026, Jun 14, 2026). You do not need to zero-pad or normalise dates for them to sort correctly. Pages whose date is missing or unrecognised sort first in ascending order (last in descending); ties keep a stable, deterministic order.

Collection Template

Each item in page.collection has the same properties as pages in children or siblings (title, url, date, author, lead, tags, order).

{% for post in page.collection %}
<article>
    <h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
    {% if post.lead %}<p>{{ post.lead }}</p>{% endif %}
    {% if post.date %}<time>{{ post.date }}</time>{% endif %}
    {% if post.tags %}
    <div class="tags">
        {% for tag in post.tags %}<a href="/tags/{{ tag }}">{{ tag }}</a>{% endfor %}
    </div>
    {% endif %}
</article>
{% endfor %}

Pagination

When content.limit is set, Accent CMS automatically paginates the collection. Pagination metadata is available in page.pagination:

PropertyTypeDescription
page.pagination.current_pageintCurrent page number (1-based)
page.pagination.total_pagesintTotal number of pages
page.pagination.total_itemsintTotal number of items in the collection
page.pagination.items_per_pageintItems shown per page
page.pagination.prev_urlstring/noneURL to the previous page (none on page 1)
page.pagination.next_urlstring/noneURL to the next page (none on last page)

Pagination URLs use the pattern /page:{num} appended to the page URL (e.g., /blog/page:2).

{% if page.pagination %}
<nav class="pagination" aria-label="Pagination">
    {% if page.pagination.prev_url %}
    <a href="{{ page.pagination.prev_url }}">Previous</a>
    {% endif %}
    <span>Page {{ page.pagination.current_page }} of {{ page.pagination.total_pages }}</span>
    {% if page.pagination.next_url %}
    <a href="{{ page.pagination.next_url }}">Next</a>
    {% endif %}
</nav>
{% endif %}

Static Build

The accent build command generates HTML files for all pagination pages. Page 1 is written to output/{path}/index.html, and subsequent pages to output/{path}/page/{num}/index.html. Pagination links in templates use the /page:{num} URL format.

Content Relationships

Pages can define named relationships to other pages via the relations frontmatter field. Each relationship is a named list of page references that are resolved into full PageMetaContext objects at render time.

Relations Frontmatter

---
title: Advanced Patterns
relations:
  series: ["part-1", "part-2", "part-4"]
  related: ["/docs/advanced", "/blog/deep-dive"]
  prerequisites: ["/docs/getting-started"]
---

References can be:

  • Absolute URLs: Starting with /, resolved directly (e.g., /docs/getting-started)
  • Relative slugs: Resolved from the current page’s parent URL (e.g., on /blog/part-3, the slug part-2 resolves to /blog/part-2)

Broken references (pointing to non-existent pages) are logged as warnings and omitted from the result. Relationship names are arbitrary strings defined by the content author.

Relations in Templates

Resolved relations are available as page.relations.<name>, where each entry is a page metadata object with title, url, date, author, lead, tags, and order.

Series navigation:

{% if page.relations.series %}
<nav class="series-nav">
    <h3>In this series</h3>
    <ol>
    {% for part in page.relations.series %}
        <li>
            {% if part.url == page.url %}
                <strong>{{ part.title }}</strong> (current)
            {% else %}
                <a href="{{ part.url }}">{{ part.title }}</a>
            {% endif %}
        </li>
    {% endfor %}
    </ol>
</nav>
{% endif %}

Related articles sidebar:

{% if page.relations.related %}
<aside class="related">
    <h3>Related Articles</h3>
    <ul>
    {% for article in page.relations.related %}
        <li><a href="{{ article.url }}">{{ article.title }}</a></li>
    {% endfor %}
    </ul>
</aside>
{% endif %}

Prerequisites notice:

{% if page.relations.prerequisites %}
<div class="prerequisites">
    <p>Before reading this, you should be familiar with:</p>
    <ul>
    {% for prereq in page.relations.prerequisites %}
        <li><a href="{{ prereq.url }}">{{ prereq.title }}</a></li>
    {% endfor %}
    </ul>
</div>
{% endif %}

The default theme template automatically renders series, related, and prerequisites relations when present.