What do the documentation means by "generate some output"?
According to the Twig documentation, whenever something generates some output, it should be a function:
Most of the time though, a tag is not needed:
- If your tag generates some output, use a function instead.
https://twig.symfony.com/doc/3.x/advanced.html#tags
It was one of the reasons of the recommendation to not use the include tag:
As of Twig 1.12, it is recommended to use the include function instead as it provides the same features with a bit more flexibility:
- The include function is semantically more "correct" (including a template outputs its rendered contents in the current scope; a tag should not display anything);
Note that, here, the wording is different: "display anything" instead of "generate output".
This is putting the documentation in a situation where however you interpret it, it contradicts itself.
Tag should not generate output
By generate, we understand "create something new".
Typically, this is what the include tag and function do: they generate some new data from an input (a template name). Here it makes sense to consider the include tag as semantically incorrect.
But this rule is contradicted by the apply tag: this tag actually generates some new data from two inputs (a list of filters and a string):
{% apply upper %}
foo
{% endapply %}
{# would generate the string "FOO" which is not part of the inputs #}
But, it is not deprecated by any mean in the documentation. Even more striking: it was added quite recently (Twig 2.9) which is way after the recommendation to not use the include tag ( Twig 1.12).
So here, if the input tag is considered as semantically incorrect, why is the apply tag not considered as such?
Same question for the autoescape tag that also violates the "should not generate output" rule.
Not how the block tag differs here and is not concerned by the issue: the block tag doesn't generate anything; it outputs as is whatever is passed to it as argument, without touching it be any mean. Hence it conforms to the rule:
- If your tag generates some output, use a function instead.
Tag should not display anything
This second interpretation - coming from the include tag documentation - makes the following tags semantically incorrect:
- apply
- autoescape
- block
- for
- if
- verbatim
All these tags, when used, display something.
{% if true %}
Foo
{% endif %}
{# displays "Foo" #}
As opposed to tags that don't display anything - and are then semantically correct.
{% macro foo() %}
Foo
{% endmacro %}
{# doesn't display "Foo" #}
So, what is the real deal?
It is very unclear what the rule is when deciding between a tag and a function. The documentation says two different things and contradicts itself in both cases.
Can you please clarify the official position of the maintainers here?
Thanks.