Guide 04 · Developer docs

Input types, layouts, components and images

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 07 · The shorthand, and working with each input type

How the area shorthand resolves

Reading an area as a property, such as {$component->heading}, is the house style for printing it. It is not sugar for a getter: it tries a real getter first, then resolves the name by the area's category and editor. The order, and what each type returns.

Who this is for. Developers writing or reviewing page and component templates. After this page you can predict what {$component->heading} returns for any area, and keep the tables below open instead of guessing.

Two ways to read an area

A template reads an area either as a property of the record or component, the shorthand, or through a getter that names it:

Template code
{* the shorthand: the house style for printing a value *}
<h2>{$component->heading}</h2>

{* a getter: for arguments, attributes and calculations *}
<h2>{$component->getAreaHtml('heading')}</h2>
{# the shorthand: the house style for printing a value #}
<h2>{{ component.heading }}</h2>

{# a getter: for arguments, attributes and calculations #}
<h2>{{ component.getAreaHtml('heading') }}</h2>

For a plain text area the two lines print the same thing, because the shorthand on text goes through getAreaHtml(). For other areas the shorthand returns something else: a real boolean, a date object, an image. Lead with the shorthand whenever you print a value with no arguments. Use a getter when you need an argument or a method on the result, when an area's name is taken by a getter of the model, or when you need plain text for an attribute, a script or JSON.

On a versioned record, such as a page, a post, a book page, a custom entity record or a global component, both forms read the active revision: {$page->getAreaText('intro')} is {$page->getActiveRevision()->getAreaText('intro')}, and {$page->intro} is the shortest way to the same content. Where that content is stored is on Where content is stored, and what a change does to it.

How it resolves

When a template reads heading as a property, the response model behind the record or component runs these steps, in order:

  1. A real getter. If the model has a method getHeading(), its result is returned. No area is consulted.
  2. An area of that name, on the frontend only. If the model belongs to the frontend abstraction (the site's own page rendering, live preview included) and holds areas, the platform reads the area's category and, for a text area, its editor, and returns the value in the form the tables below give.
  3. An error. If the name is neither a getter nor an area, the model throws Property heading does not exist in, followed by its class name.

The sequence is identical in both engines. Twig's attribute lookup reaches the same property and method handling as Smarty's ->, so steps 1 and 2 behave alike. The engines differ only in what the reader sees at step 3: Smarty fails the page, Twig prints nothing. That difference, and the other limits, are on Limits of the shorthand, and the rule.

What each category returns

Area categoryThe shorthand returnsThe same as
imageThe image object; on the frontend a blank image when the area is emptygetAreaImage()
fileThe file object, or nullgetAreaFile()
recordThe linked record, or nullgetAreaRecord()
recordsA collection of the linked records, or nullgetAreaRecords()
textDepends on the editor, in the next table
component, collection and the restThe rendered block, as HTMLgetAreaHtml()

Images have a unit of their own, starting at Images in templates. Files, records and blocks in practice are on Files, records and component areas.

What each text editor returns

Text editorThe shorthand returns
switchA real boolean: true when the stored text is 1, otherwise false
date, datetimeA printable date object, which prints in the site's date format and takes date methods such as format(); null when empty
Every other editor (text, textarea, rich text, select, number, code and the rest)The stored text, through getAreaHtml()

These three exceptions are the ones to memorise. A switch and a date never carry the live-preview wrapper, because they are a boolean and a date object rather than text, so they are safe to test and compare through the shorthand:

Template code
{* switch: a real boolean *}
{if $component->hideDate}...{/if}

{* date: an object, or null; printed as it is, it uses the site's date format *}
{if $component->eventDate}
    <p class="date">{$component->eventDate}</p>
{/if}
{# switch: a real boolean #}
{% if component.hideDate %}...{% endif %}

{# date: an object, or null; printed as it is, it uses the site's date format #}
{% if component.eventDate %}
    <p class="date">{{ component.eventDate }}</p>
{% endif %}

Every other text value is HTML from getAreaHtml(), and in the admin's live preview that HTML is wrapped in an editable marker. What that gives you, and what it costs inside attributes, is on The shorthand and live preview. How each input type is stored and printed is on Text, select and switch areas in templates and the two pages after it.

A getter of the same name wins

Step 1 comes first, so an area called name, id, url, slug or fullPath returns the model's own value, not the author's content, and raises no error. Name areas for what they hold, such as heading or ctaUrl. More on a real getter wins.

Go deeper

Was this page helpful?

Your answer goes to the docs team.