Core dna renders server-side sites with Smarty or with Twig, one engine per site, and treats the two as peers. This guide is the one place both are documented: what they share, each engine's language and the platform's additions and limits, the two side by side, and translation.
L1–L2
Unit 03 · Twig
Twig in Core dna
TwigPage 14 of 25Updated
Core dna runs Twig 3.19 with the string extension, autoescaping switched off, strict variables off, no sandbox and a set tag of its own. How the platform configures it, where Twig files live and what they are called, how it differs from the upstream manual, and where errors and debug output show.
Who this is for. The developer starting on a Twig site, whether they know Twig from elsewhere or Core dna from Smarty sites. Afterwards you will know what the platform changes about stock Twig, which page of this unit covers each part, and how to see what went wrong when a template fails.
How the platform configures Twig
Twig is a full peer of Smarty on Core dna: a site set to Twig renders every template with it, and everything in The shared model applies unchanged. What is specific to Twig:
Setting
On Core dna
Read more
Version
Twig 3.19, plus the string extension (twig/string-extra 3.8). No other extra package
Where Twig templates live, and what they are called
Twig templates live in the same templates/ folder as on any site and are found through the same resolution order. Most end in .html, not .twig, which surprises developers from other platforms. The extension means nothing to the engine; it matters only to the admin's layout picker, which offers files ending in .html, .tpl or .twig. A Twig repository typically looks like this:
Shell
templates/
includes/
base.html the base template every page extends
elements/anchor-link.html a partial, included by name
utilities/geo.twig a macro library, only ever imported
components/
hero.html a component layout's template
accordion.html
pages/pages/
show.html the default page template
landing.html a page layout's template
blogs/posts/
show.html
errors/
not-found.html
A convention many Twig sites follow, and a sensible one: .html for anything a layout points at or a controller renders, .twig for files only ever reached from another template, such as macro libraries. Either works in either role.
Nothing is escaped automatically
Stock Twig escapes every {{ }} by default. Core dna switches autoescaping off, so {{ value }} prints exactly the string it is given, as Smarty's {$value} does. Two consequences:
You escape deliberately. A value that came from a visitor, a URL or an imported feed needs |e (short for |escape) written by you. A richtext area holds HTML on purpose and is printed as it is.
|raw changes nothing here. It is not wrong, only redundant, and a template full of it suggests the author expected autoescaping.
This is the assumption most likely to follow a Twig developer from another platform, and the usual advice that “Twig is safe by default” does not hold here: neither engine escapes unless asked. Twig security gives the review question to ask about every output.
An undefined variable prints nothing
Templates render with strict variables off. An undefined variable, an attribute a record does not have, and a misspelt method all print nothing, with no error and no log entry. That is why Twig templates lean on |default(…), ?? and is defined, and why a blank value in Twig should make you check the spelling before the content (Response models).
The one render with strict variables on is a Mailer email's subject and body on a Twig site. There an undefined variable makes the render fail, and the platform falls back to plain placeholder substitution, so the mail is sent without the Twig in it taking effect (The one strict render). Strictness is useful there: a merge field that is not defined is a mistake you would rather catch than send as a blank. If a merge field works on the site and not in an email, test it with every variable defined.
dump(), trans, {% sandbox %}, {% cache %} and the intl, html and markdown extras are not installed. Each is a compile error that fails the whole template.
A site cannot register an extension. A theme has no PHP, and the platform's environment takes no extensions from a site; reusable logic goes in macros (Add a filter or extension to a Twig site).
Where errors show
An unknown filter, function, tag or test is found when the template compiles, so the whole template fails, not only the one expression. An exception thrown while rendering, such as a coercion filter given null, fails the render the same way. Twig's message names the template and the line: Unknown "dump" function in "components/hero.html" at line 12. A development environment shows it on a stack-trace page; production shows the site's errors/fatal-error.html and logs the message.
Debugging
See what the controller passed: add ?dev=1 to the URL on a development environment; on production the panel appears only to a signed-in backend user of type developer.
Dump a value you choose:{{ debug_vars(page, component) }} or {{ page|debug_vars }} adds it to the same panel on a development environment and prints nothing anywhere else.
Test, do not assume: since nothing undefined raises an error, render the page with the content you expect and look for blanks.