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 06 · Rendering areas in templates
Testing whether an area is empty
Rendering areas in templatesPage 24 of 45Updated
An area can be empty in four ways, and the getters report it as null, an empty string or array, a blank object or an empty collection. The test for each getter, the one check that covers every category, and why empty() is never true for an object in Smarty.
Who this is for. The template developer hiding a heading, a wrapper or a whole section when its area has nothing in it. Afterwards you can test any area correctly, in either engine, without a fatal error on an empty one.
Four ways to be empty
Never filled. The author never set the area.
Filled, then cleared. In a template this reads exactly like never filled.
An empty collection. A collection area with no elements.
A component with nothing in it. The area holds a component, or a collection holds an element, whose own areas are all empty.
The fourth is invisible from outside: the component exists, so it is not blank. Decide it inside that component's own template, where its areas are read.
The test for each getter
Each getter reports an empty area in its own way, so each takes its own test. Calling a method on null is a fatal error, so use a method test only where the getter always returns an object.
Getter
Empty area returns
Empty in Smarty
Empty in Twig
The shorthand on a text area, getAreaText(), getAreaHtml()
null ('' from getAreaHtml() and the shorthand; false from the shorthand on a switch)
{if !$text}
{% if not text %}
getAreaValues()
[]
{if empty($values)}
{% if values is empty %}
getAreaDate()
null
{if !$date}
{% if not date %}
getAreaImage(), getAreaComponent()
A blank object
{if $image->isBlank()}
{% if image.isBlank() %}
getAreaFile(), getAreaRecord(), getAreaRecords()
null
{if !$file}
{% if not file %}
getAreaCollectionElements()
An empty collection
{if $items->count() == 0}
{% if items.count() == 0 %}
One check for every category
When a template does not know what kind of area it is testing, test the content rather than the getter's result. In a template, getAreaContentOrDefault(name) returns a content object whatever the area holds, a blank one when nothing is stored, and it works on every container, versioned records included. Its isEmpty() answers for every category:
blank content (never filled, or cleared) is always empty;
an image or component area is empty when it holds the blank image or component;
a collection is empty when no element is left once blank elements are set aside;
text is empty when it is an empty string or null, a file area when there is no file, and a record or records area when no id is stored.
Template code
{if $component->getAreaContentOrDefault('hero')->isEmpty()}
{* the area is empty, whatever its category *}
{/if}
{% if component.getAreaContentOrDefault('hero').isEmpty() %}
{# the area is empty, whatever its category #}
{% endif %}
It sees only the area itself: a component inside the area whose own areas are empty still counts as filled, the fourth case above.
The practical use is a generic template that prints every filled area of a layout, skipping attributes and empty areas:
{% for area in component.getLayout().getAreas() %}
{% if not area.isAttribute() %}
{% set content = component.getAreaContentOrDefault(area.getName()) %}
{% if not content.isEmpty() %}
<div class="field field--{{ area.getName() }}">{{ component.getAreaHtml(area.getName()) }}</div>
{% endif %}
{% endif %}
{% endfor %}
Why empty() is never true for an object in Smarty
empty() is never true for an object
Smarty allows PHP's empty(), and PHP never treats an object as empty, whatever it holds. {if empty($page->getAreaImage('hero'))} is always false, even when the area is empty and the getter returned the blank image. Use the object's own isBlank() or isEmpty().
Twig's is empty test does work on blank objects, because Core dna replaces Twig's own: it treats an object that prints as an empty string as empty, and every blank object prints as an empty string. A real record or other model is never empty to it, so the test never renders a record to find out. These two lines do the same thing:
Template code
{if $page->getAreaImage('hero')->isBlank()}
{* no hero image *}
{/if}
{% if page.getAreaImage('hero') is empty %}
{# no hero image #}
{% endif %}