Sections & data
Charities don’t edit pages, they compose them from sections. Each page holds an ordered list of sections drawn from a closed catalogue; each section carries typed content the charity authored in their admin. Your template’s job is to render whatever subset of that they actually wrote.
The render context
Section titled “The render context”A section renderer receives exactly two things (see Render context):
section, the typed content of the section being rendered. Its shape is the section type’s fields; consult the catalogue per type.brand,brand.nameandbrand.tagline, the charity’s identity.
That’s the whole surface. No API access, no other tenants, no secrets, and the context only ever grows within a contract major, so new variables can appear but existing ones never vanish or change shape.
Escape-by-default
Section titled “Escape-by-default”Every {{ output }} is HTML-escaped. The single opt-out is | raw, and the only fields you
should ever pass through it are the catalogue’s richtext fields (like hero.bodyHtml), the
platform sanitises those server-side on save, before a template ever sees them.
<h1>{{ section.title }}</h1> <!-- escaped: always safe -->{{ section.bodyHtml | raw }} <!-- sanitised richtext: the one legitimate raw -->{{ section.title | raw }} <!-- NEVER: plain text doesn't get raw -->Sparse data is normal, degrade, don’t decorate
Section titled “Sparse data is normal, degrade, don’t decorate”Every section is independently omittable, and inside a section most fields are optional. The validator renders your template against each type’s minimal fixture, the least a charity can author, and your renderer must produce something sensible.
The pattern: wrap optional output in a condition, or give it an honest default.
{% if section.eyebrow %}<p class="lq-kicker">{{ section.eyebrow }}</p>{% endif %}<h2>{{ section.heading | default: "What guides us" }}</h2>The truthfulness rule
Section titled “The truthfulness rule”Derive or omit, never fabricate. A template must not invent claims on a charity’s behalf: no placeholder impact numbers (“10,000 meals served”), no fake testimonials, no invented history. If the charity didn’t author it and the platform can’t derive it from real data, the space doesn’t render. A generic default like a heading (“What guides us”) is fine; a factual-sounding claim is not. This is a publish-gate policy, not just style guidance, template review checks for it.
Field kinds
Section titled “Field kinds”| Kind | What it is | How to render |
|---|---|---|
text |
Plain text | {{ section.field }} (escaped) |
richtext |
Sanitised HTML from the platform editor | `{{ section.field |
url |
A link, scheme-guarded on save | href="{{ section.field }}" |
icon |
An emoji, or a Lucide icon name such as heart-handshake |
{{ item.icon }}. When the name is a Lucide icon the platform also supplies item.iconSvg (platform-generated markup, safe for raw): `{% if item.iconSvg %}{{ item.iconSvg |
items |
A list of objects (see the type’s itemFields) |
{% for item in section.items %} |
Platform-data sections
Section titled “Platform-data sections”These sections have no author-editable fields in the admin, their content is the tenant’s live data, provided to your renderer:
| Section | Context | What it is |
|---|---|---|
events |
events[] |
Upcoming ticketed events (curated event shape, name, startsAt, venueName, priceFrom, soldOut, detailHref…) |
whatsOn |
infoEvents[] |
Info events (special days, no sign-up), same shape |
articles |
latestArticles[] |
Newest published articles (up to 6): title, href, excerpt, imageUrl, publishedAt, readingMinutes, categories |
campaigns |
campaigns[], campaignsLabel |
Live campaigns in display order (title, href, summary, imageUrl) plus the tenant’s chosen section label, always link via href |
appealGrid, emergency |
causes[] |
Active appeals with target, raised amount, progress percentage and the platform donation href |
programmes |
services[] |
Published services with summary, image and platform-provided href |
resources |
resources[] |
Public document links only; private media and storage metadata are excluded |
locations |
locations[] |
Public venues with safe directions links; provider references and admin notes are excluded |
Render them your way, or place the section’s default island and ignore the context entirely, see islands. Empty lists must render nothing: derive or omit.
Collection drops are deliberately curated projections rather than raw service responses. Use their
supplied href or url fields. Do not construct storage, payment, event or service routes inside a
template.

