Documentation
Cross-linking pages with all_pages
Every template in markdown-mode sites has access to a global all_pages variable — a list of every .md page in the site with its full frontmatter. This lets any layout pull in and filter content from other sections without any special configuration.
How it works
Every page summary in all_pages carries these fields:
| Field | Example | Description |
|---|---|---|
title | "Alice Müller" | From frontmatter title: |
url | "/users/alice" | Absolute URL of the page |
slug | "alice" | Last path segment |
section | "/users" | Parent path |
extra | {location: "lake-constance"} | All other frontmatter fields |
extra_lists | {hosts: ["alice","bob"]} | List-valued frontmatter fields |
tags | ["guide","beginner"] | Tag list |
date | "2026-06-15" | Frontmatter date |
snippet | "A gentle paddle…" | First ~200 chars of body |
You filter all_pages in templates using Tera's built-in filter filter with attribute paths:
{% set guides = all_pages | filter(attribute="section", value="/users") %} {% set here = all_pages | filter(attribute="extra.location", value="lake-constance") %}
Tutorial: users, activities, and locations
This example builds a small site with three entity types that link to each other.
Content files
users/alice.md
--- title: Alice Müller location: lake-constance role: guide --- Alice has been leading kayak tours since 2019 and knows every cove on the lake.
activities/morning-kayak.md
--- title: Morning Kayak Tour location: lake-constance host: alice date: 2026-06-15 duration: 3h level: beginner --- A gentle paddle along the northern shore, suitable for all fitness levels.
locations/lake-constance.md
--- title: Lake Constance region: southern-germany --- Bordered by Germany, Austria, and Switzerland, Lake Constance offers calm waters and dramatic Alpine views.
magic-circle.md — a standalone view page with no body:
--- title: The Magic Circle layout: magic-circle ---
Layouts
Create these files under layouts/ in your site's git repository.
layouts/user-profile.html — resolves the user's location, lists their activities:
{% extends "base.html" %} {% block main %} <h1 class="title">{{ page.title }}</h1> <p class="text-muted">{{ page.extra.role }}</p> {{ page.content | safe }} {% set location = all_pages | filter(attribute="slug", value=page.extra.location) | first %} {% if location %} <p>Based at <a href="{{ location.url }}">{{ location.title }}</a></p> {% endif %} {% set activities = all_pages | filter(attribute="section", value="/activities") | filter(attribute="extra.host", value=page.slug) %} {% if activities %} <h2>Activities</h2> {% for a in activities %} <div class="mb-2"> <a href="{{ a.url }}">{{ a.title }}</a> <span class="text-muted ms-2 small">{{ a.extra.date }} · {{ a.extra.level }}</span> </div> {% endfor %} {% endif %} {% endblock %}
layouts/activity.html — links back to its location and host:
{% extends "base.html" %} {% block main %} <h1 class="title">{{ page.title }}</h1> <div class="text-muted mb-3"> {{ page.extra.date }} · {{ page.extra.duration }} · {{ page.extra.level }} </div> {{ page.content | safe }} {% set location = all_pages | filter(attribute="slug", value=page.extra.location) | first %} {% set host = all_pages | filter(attribute="slug", value=page.extra.host) | first %} <div class="mt-3 d-flex gap-4"> {% if location %} <span>Location: <a href="{{ location.url }}">{{ location.title }}</a></span> {% endif %} {% if host %} <span>Guide: <a href="{{ host.url }}">{{ host.title }}</a></span> {% endif %} </div> {% endblock %}
layouts/location.html — aggregates activities and guides for this location:
{% extends "base.html" %} {% block main %} <h1 class="title">{{ page.title }}</h1> {{ page.content | safe }} {% set activities = all_pages | filter(attribute="section", value="/activities") | filter(attribute="extra.location", value=page.slug) %} {% if activities %} <h2>Activities here</h2> {% for a in activities %} <div class="mb-2"> <a href="{{ a.url }}">{{ a.title }}</a> <span class="text-muted ms-2 small">{{ a.extra.date }} · {{ a.extra.level }}</span> </div> {% endfor %} {% endif %} {% set guides = all_pages | filter(attribute="section", value="/users") | filter(attribute="extra.location", value=page.slug) %} {% if guides %} <h2>Guides based here</h2> {% for u in guides %} <div><a href="{{ u.url }}">{{ u.title }}</a></div> {% endfor %} {% endif %} {% endblock %}
layouts/magic-circle.html — a free-form view that aggregates all three entity types:
{% extends "base.html" %} {% block main %} <h1 class="title">{{ page.title }}</h1> <div class="row g-4"> <div class="col-md-4"> <h2>Locations</h2> {% for loc in all_pages | filter(attribute="section", value="/locations") %} <div class="card mb-2 p-2"> <a href="{{ loc.url }}">{{ loc.title }}</a> {% set count = all_pages | filter(attribute="section", value="/activities") | filter(attribute="extra.location", value=loc.slug) | length %} <small class="text-muted d-block">{{ count }} activit{{ count | pluralize(singular="y", plural="ies") }}</small> </div> {% endfor %} </div> <div class="col-md-4"> <h2>Upcoming Activities</h2> {% for a in all_pages | filter(attribute="section", value="/activities") | sort(attribute="extra.date") %} <div class="mb-2"> <a href="{{ a.url }}">{{ a.title }}</a><br> <small class="text-muted">{{ a.extra.date }} · {{ a.extra.level }}</small> </div> {% endfor %} </div> <div class="col-md-4"> <h2>Guides</h2> {% for u in all_pages | filter(attribute="section", value="/users") %} <div class="mb-2"> <a href="{{ u.url }}">{{ u.title }}</a> <small class="text-muted d-block">{{ u.extra.role }}</small> </div> {% endfor %} </div> </div> {% endblock %}
Wiring up the layouts
Each content file needs to reference its layout in frontmatter. Add layout: to the files that use a custom layout (the section _index.md is a good place for this):
users/_index.md
--- title: Guides layout: list ---
users/alice.md — add layout: user-profile:
--- title: Alice Müller layout: user-profile location: lake-constance role: guide ---
activities/morning-kayak.md — add layout: activity:
--- title: Morning Kayak Tour layout: activity location: lake-constance host: alice date: 2026-06-15 duration: 3h level: beginner ---
locations/lake-constance.md — add layout: location:
--- title: Lake Constance layout: location region: southern-germany ---
Result
| URL | Content |
|---|---|
/users/alice | Alice's bio + her location link + her activities |
/activities/morning-kayak | Activity details + location link + guide link |
/locations/lake-constance | Location description + all activities + all guides there |
/magic-circle | Three-column overview of all entities |
Every link is resolved at render time by filtering all_pages — no foreign keys to declare, no joins to configure.
Filtering reference
| Goal | Template expression |
|---|---|
| All pages in a section | all_pages | filter(attribute="section", value="/users") |
| Page with a specific slug | all_pages | filter(attribute="slug", value="alice") | first |
| Pages matching a scalar field | all_pages | filter(attribute="extra.location", value=page.slug) |
| Sort by a field | … | sort(attribute="extra.date") |
| Count matches | … | length |
| First match or nothing | … | first (returns undefined if empty — guard with {% if … %}) |