Twig Templating
What this domain covers
Twig is Drupal's templating engine. Questions probe syntax, autoescaping, filters and functions, whitespace control, and the security model. You need to know what Twig does automatically and what requires explicit action.
Concepts to know
- Delimiters:
{{ }}prints,{% %}runs logic,{# #}comments. - Autoescaping: Twig escapes output by default in HTML context. Use
|rawonly when output is trusted; it disables escaping and is a common source of XSS. - Filters:
|ttranslates,|lengthcounts,|joinconcatenates,|dateformats,|defaultsupplies fallbacks,|clean_classand|clean_idsanitize for CSS. - Functions:
path(),url(),attach_library(),link(),create_attribute(). - Control structures:
{% if %},{% for %},{% set %},{% include %},{% extends %},{% block %}. - Whitespace control:
{{- -}}and{%- -%}trim adjacent whitespace. - Debugging:
{{ dump() }}when Twig debug is enabled;{{ kint() }}via Devel.
Traps in questions
A classic trap is applying |raw to user-supplied content, which reintroduces XSS. Another is assuming |t escapes for you - it translates but does not replace the need for contextual escaping. Questions may also conflate path() (returns a relative URL) with url() (returns an absolute URL). Watch for {% include %} vs {% embed %}: embed allows overriding blocks.
Rule of thumb
Escape by default, and only reach for |raw when the value is generated by trusted code - never for user input. Prefer passing render arrays over pre-rendered HTML strings.
Worked example: To link a node title safely: <a href="{{ path('entity.node.canonical', {'node': node.id}) }}">{{ node.label }}</a>. The path() function returns a relative URL and node.label is autoescaped, so no |raw is needed.