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
The shorthand and live preview
The shorthand, and working with each input typePage 26 of 45Updated
In the admin's live preview, the shorthand keeps every text area editable in place, while getAreaText() keeps only rich text editable. The wrapper that does it, a before and after, why it breaks attributes, and why the shorthand survives an editor change.
Who this is for. Developers whose authors edit in the admin's live preview, and reviewers checking templates. After this page you can say why a field stopped being editable in the preview, and keep both in-place editing and attributes working.
What live preview adds
Live preview shows the page as the author edits it, and lets them type straight into it. For that, the platform wraps each editable text value in a marker element that carries the path to its area. The wrapper is added only on the frontend, and only when the render asks for live-preview tags (insertLivePreviewTags), as the live preview's render does. Visitors never get it. The full markup, for a heading:
data-path identifies the area; the id is live-preview-container- followed by the same path, base64-encoded; style="all:inherit" keeps the span from changing how the text looks.
Which reads are wrapped
Read
Text area (text, textarea, select and the rest)
Rich text area
The shorthand, {$component->heading}
Wrapped
Wrapped
getAreaHtml('heading')
Wrapped
Wrapped
getAreaText('heading')
Not wrapped
Wrapped, without style="all:inherit"
A switch or a date read through the shorthand is never wrapped: the shorthand returns a boolean or a date object for those, not text.
Before and after
For a plain text heading, both versions print the same text to visitors. In live preview only the shorthand version can be edited in place:
Template code
{* before: getAreaText() on a text area has no wrapper,
so live preview cannot edit the heading in place *}
<h2>{$component->getAreaText('heading')}</h2>
{* after: the shorthand is wrapped, so the author types straight into it *}
<h2>{$component->heading}</h2>
{# before: getAreaText() on a text area has no wrapper,
so live preview cannot edit the heading in place #}
<h2>{{ component.getAreaText('heading') }}</h2>
{# after: the shorthand is wrapped, so the author types straight into it #}
<h2>{{ component.heading }}</h2>
Nothing looks wrong with the getter version, on the site or in the preview. The field is not editable in place, which is why teams rarely notice they have lost it. This is the strongest argument for the shorthand.
The cost: never inside an attribute
The wrapper is markup. In element content that is what you want; inside an HTML attribute it breaks the tag, and only in live preview, so visitors never see the fault and authors do. The same holds wherever the value is not printed as element content: in a script, in JSON, in a comparison or a calculation, the shorthand gives the wrapped text in live preview, not the stored value. Read plain text there with getAreaText():
Template code
{* breaks in live preview: the class attribute receives a span *}
<section class="banner {$component->width}">
{* correct: plain text in attributes, the shorthand in content *}
<section class="banner {$component->getAreaText('width')}">
<a class="{$component->getAreaText('cssClasses')}" href="{$component->getAreaText('ctaUrl')}">{$component->linkName}</a>
</section>
{* comparisons too *}
{if $component->getAreaText('width') == 'full'}...{/if}
{# breaks in live preview: the class attribute receives a span #}
<section class="banner {{ component.width }}">
{# correct: plain text in attributes, the shorthand in content #}
<section class="banner {{ component.getAreaText('width') }}">
<a class="{{ component.getAreaText('cssClasses') }}" href="{{ component.getAreaText('ctaUrl') }}">{{ component.linkName }}</a>
</section>
{# comparisons too #}
{% if component.getAreaText('width') == 'full' %}...{% endif %}
On the live site both versions of the section render identically; the difference only shows up for an author, while editing. The switch and date exceptions hold here too: {if $component->hideDate} is safe, because the value is a boolean.
The other advantage: an editor change needs no template change
The shorthand never assumes which text editor an area has. If an area is later switched from plain text to rich text in the admin, a template that prints it with the shorthand keeps working, and the field stays editable in live preview before and after:
Template code
{* area "summary": a Text area today, rich text tomorrow;
the template does not change *}
<div class="summary">{$component->summary}</div>
{# area "summary": a Text area today, rich text tomorrow;
the template does not change #}
<div class="summary">{{ component.summary }}</div>
HTMLWhat visitors receive
<!-- summary as a Text area -->
<div class="summary">Three offices, one team.</div>
<!-- the same area after the switch to rich text -->
<div class="summary"><p>Three offices, <strong>one team</strong>.</p></div>
Wrap for the richest editor
Choose the element around a shorthand for the richest editor the area might get. A div can hold the paragraphs rich text produces; an h2 or a p cannot.