The platform's central abstraction, in one line: an input type defines what an editor can enter, a layout area binds one input type to a named slot, a layout groups areas and points at a template, a record or component holds the content for each area, and the template reads it back. Read this book straight after the template languages.
L1–L3
Unit 01 · The model, end to end
The chain from input type to template
The model, end to endPage 1 of 45Updated
Five links carry every piece of content to the page: an input type, a layout area, a layout, a record or component, and the template. What each link is, where it lives, why a new page type starts in the admin, and the word "area", which means two things.
Who this is for. Every theme developer and content modeller, before any other page of this guide. After it you can name the five links between an editor's field and the HTML it produces, say where each one is defined, and tell which one is missing when a page renders blank.
The chain
Each arrow below answers one question. Every later page of this guide is about one link or one arrow, and refers back to this picture.
The chain
INPUT TYPE Richtext, Image, "Section style" (a select) ...
| What kind of value can an editor enter?
v
LAYOUT AREA name "body", label, help, required, default ...
| Which named slot, with which rules?
v
LAYOUT name, template pages/pages/article.html, controller, its areas
| Which template renders these slots, and for which records?
v
RECORD or a page, a blog post, a book page, a component ...
COMPONENT What did the editor enter in each slot?
| (stored in its active revision, one content row per area)
v
TEMPLATE {$page->body} {{ page.body }}
How is the value shown? (asks for the slot by its name)
Link
What it is
Where it is defined
Input type
A kind of value: its category (text, image, file, component, collection, record, records) and, for text, its editor (plain text, rich text, select, switch, date and nine more). The name is a label; the category and editor decide behaviour.
Customization › Input Types. Shared by every site of the client.
Layout area
One input type placed on one layout under a name, with a label, help text and rules.
On the layout, under Customization › Layouts. The name is unique within the layout.
Layout
A set of layout areas, the template that renders them, and a controller that says which records may use it (none for a component).
Customization › Layouts.
Record or component
The thing an editor fills in. It uses one layout; its content is stored in revisions, and the active revision holds one content row per layout area it has a value for. A component is stored with the revision that holds it.
The content screens: Pages, Blogs, Books and the rest; a component inside another record's area.
Template
The file that reads each value back by the layout area's name.
Your theme repository, at the path the layout names.
In a template, the five links meet in one expression:
Template codetemplates/pages/pages/article.html
{* page: the record; 'heading', 'heroImage', 'body': layout area names *}
<h1>{$page->heading}</h1>
{$page->getAreaImage('heroImage')->getResized(1200, 600, 'fit')->getHtml()}
{$page->body}
The shorthand, {$page->body} in Smarty and {{ page.body }} in Twig, is the normal way to print a value: it resolves by the area's category, so text prints as text and an image comes back as an image object. The getters are the explicit form, one per category of input type: getAreaText() for text, getAreaImage() for an image, getAreaHtml() for anything rendered. Use a getter when you need an argument or a method on the result, as with the image above, or plain text inside an HTML attribute. On a page, a blog post or any other versioned record, both forms read the record's active revision: $page->getAreaText('heading') is $page->getActiveRevision()->getAreaText('heading'). Which getter to use, and what each returns when the area is empty, is the subject of Area getters, by return type.
Why a page type starts in the admin
The template is the last link. A file that no layout points at is never rendered, however correct it is, and a layout with no records using it is never requested. So a new kind of page is built in this order:
Deploy a template file, even a placeholder: the layout form offers only files that are on the server.
Create the layout, pointing at the file, and its layout areas.
Create a record that uses the layout, and fill it in.
Write the real markup, reading the areas by name.
The planning consequence: the layout, its area names, labels, help text and rules are a design task with an owner, agreed before the markup is written, not something that falls out of it. Area names in particular are hard to change later, for the reasons on Where content is stored, and what a change does to it. Start with a placeholder template walks the order once with a throwaway page type.
"Area" means two things
The admin and the code use "area" for both ends of the chain:
the slot, defined once on a layout: its name, input type, label and rules. The code calls it a layout area;
the value an editor entered in that slot on one record. The code stores it as a content row, linked to a revision of the record by an area row.
The habit that keeps them apart: say layout area for the slot and content for the value, and when a sentence says only "area", ask "on the layout, or on the record?" Renaming, hiding, deleting and changing a type are done to a layout area, and they affect the content of every record that uses the layout at once. A template expression such as {$page->heading} crosses the line: it takes a layout area's name and returns one record's content, from its active revision.