Twig templates can declare the types they expect, but until now they had no standard way to describe what their variables, blocks and macros represent.
The Problem
Projects that document template APIs often rely on custom conventions inside
regular Twig comments. A component library, for example, might use annotations
such as @prop and @block:
1 2 3 4 5 6 7 8 9 10
{# @prop id string Unique identifier for the accordion #}
{# @prop multiple boolean Whether several items can be open #}
{# @block content The accordion items #}
{% types {
id: 'string',
multiple?: 'boolean',
} %}
{% block content %}{% endblock %}
These annotations duplicate variable names and types already present in the
types declaration. They also require every IDE, static analyzer and
documentation generator to understand a project-specific format.
Documentation Comments
Twig 3.29 introduces documentation comments, a standard syntax for attaching
human-readable descriptions to template constructs and variable declarations.
They use the regular Twig comment delimiters with an additional #:
1 2 3 4
{## The accordion items displayed by this component. ##}
{% block content %}
...
{% endblock %}
Documentation comments can describe output expressions, built-in and custom tags, blocks and macros. The comment is associated with the construct that immediately follows it:
1 2 3 4 5 6 7
{## Displays the title of the current page. ##}
{{ page_title }}
{## Renders an HTML input. ##}
{% macro input(name, value = null) %}
...
{% endmacro %}
Consecutive documentation comments are combined, which lets you add more context without writing a long line:
1 2 3
{## Displays the main page content. ##}
{## The layout renders this block between the header and footer. ##}
{% block content %}{% endblock %}
Documenting Variable Bindings
Inside a Twig tag, documentation comments start with ## and continue until
the end of the line. This keeps descriptions next to the declarations they
explain without repeating names or types:
1 2 3 4 5 6 7 8 9 10
{% types {
## Unique identifier for the accordion.
id: 'string',
## Whether several items can be open at the same time.
multiple?: 'boolean',
## Value of the item that should initially be open.
default_value?: 'string|null',
} %}
The existing types syntax remains unchanged. Required variables still use a
plain name and optional variables still use the ? suffix. Documentation is
additional metadata associated with each declaration.
The same syntax can describe assignment targets, loop variables and macro arguments:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
{% set
## The number of unread messages.
unread_count = messages|filter(message => not message.read)|length
%}
{% for
## The product identifier.
product_id,
## The product for the current iteration.
product
in products
%}
...
{% endfor %}
{% macro input(
## The HTML field name.
name,
## The initial field value.
value = null,
) %}
...
{% endmacro %}
Because an inline documentation comment consumes the rest of its line, the variable it describes must begin on a later line. Comments in unsupported positions remain regular comments and expose no metadata.
Metadata for Developer Tools
Documentation comments do not change compiled output or rendering. Twig
attaches their contents to the parsed nodes, where node visitors can read them
with Node::getDocumentation().
This gives tools a common source of metadata. An IDE can display descriptions during autocompletion, a static analyzer can include them in diagnostics and a component documentation generator can build an API reference directly from the template. The Twig declarations remain the source of truth for names, types and optionality.
Note
Symfony Language Tools understands Twig documentation comments.
For variables declared with the types tag,
completion and hover include the declared type, required or optional status
and attached documentation.
Backward Compatibility and Experimental Status
The syntax was designed to degrade gracefully. Older Twig versions parse
{## ... #} as a regular comment. Twig 3.15 and later also parse ##
inside a tag as an ordinary inline comment, so templates using these versions
can add documentation comments without changing their rendered output.
Documentation comments are experimental in Twig 3.29. Their syntax and metadata API can evolve based on feedback from template authors and tooling developers.