Topic
8 how-tos
Templates in both engines
Tell whether a site is Smarty or Twig in thirty seconds
Open any file under templates/ and read the delimiters. Braces with a dollar sign are Smarty; double braces and percent tags are Twig. The file extension proves nothing; the setting is Globals.template.engine, set in the site's .settings.json.
Set up a base template and extend it
One base template holds the document, the head, the chrome and the script queue, and defines blocks. Every page-type template extends it and fills the blocks. Both engines do this the same way.
Pass a variable across an inheritance boundary
An assignment at the top of a child template, outside any block, reaches the parent everywhere. An assignment inside a block does not: Smarty sees it only after the block, Twig never. For components, use the template context.
Share a partial between several page types
Put the fragment in includes/, pass what it needs by name, and never let it read the page's record directly, because the record arrives under a different name on every page type. Document its inputs at the top.
Call a PHP function from a Smarty template, and find out why one is blocked
Call the function, do not pipe to it: trim($x) compiles, $x|trim does not. Ninety-eight PHP functions are callable, seven are allowed as modifiers, and Smarty's own modifiers always work. The error names the call.
Add a filter or extension to a Twig site
You cannot: a theme has no PHP and the platform registers no site extensions. What you can do is a library of macros imported under one name, plus the core filters, the string extension and the platform's own additions.
Add translation to a Twig site, which has no trans filter
Twig has no trans filter here, but every render receives the translator as __. Call __.translate(key, params, domain), wrap it in a macro that fixes the domain, and keep the keys in XLIFF files under translations/.
Port one template from Smarty to Twig
Keep the file name, change the contents. Carry escaping across one for one, translate calls second, scope assignments third, then diff the rendered page before and after. Here is one template ported end to end.