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 … %}) |