You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If an expression {{ }} or statement {% %} is directly followed by a linebreak, which is pretty often, it seems to be automatically removed.
For instance:
<tag>
{% setnothing=42 %}
</tag>
would output:
<tag>
</tag>
and not:
<tag>
</tag>
If we extend this reasoning, wouldn't it make sense to also trim spaces at the left of the expression/statement, in the case there are only spaces at the start of the line?
To illustrate, let's reuse previous example with indentation:
<tag>
{% setnothing=42 %}
</tag>
It now outputs:
<tag>
</tag>
Currently, to maintain a good indentation, I always use a left space-only trim ~:
<tag>
{%~ setnothing=42 %}
</tag>
The use of ~ being pretty much systematic, I think it would be fully legitimate to infer it when the left part of the current line contains only spaces. I would agree that deciding to remove left spaces would mean that we would force the removal of "information" that, in some case that I cannot think of at the moment, some might actually want to preserve. Then, once again, Twig already does something similar by implicitly removing some linebreaks.
Therefore, I think a more natural way to deduce removable content would be to arbitrate on the whole line: if only composed of spaces apart from the statement, the whole line would be trimmed, including the ending linebreak, otherwise none of it. Moreover, this rule makes sense on a statement or comment, but not so much on an expression, which is expected to output something.
Two last exemples:
<tag>{% fornin0..3 %}
{{ n }}
{% endfor %}</tag>
outputs:
<tag> 0
1
2
3
</tag>
whilst I believe one could legitimately expect to obtain instead:
<tag>
0
1
2
3
</tag>
And:
<tag>{# Some comment #}
</tag>
outputs:
<tag></tag>
whilst we could expect instead:
<tag>
</tag>
To sum up, the idea is quite simple: if a whole line (including the finishing CR/LF) is only composed of spaces, comments and statements, it shouldn't be rendered. Otherwise, everything should be preserved (including the finishing CR/LF).
I have question about whitespace control related to this. My test scenario:
--TEST--
Test line ending
--TEMPLATE--
{# without modifiers #}
first line {% if 1 > 0 %}1{% endif %}
and second line on new line
first line {% if 1 > 0 %}2{% endif %}{# with comment at end line #}
and second line on new line
{# with triminig whitespace except newline #}
first line {%~ if 1 > 0 %}3{% endif ~%}
and second line on new line
{# with whitespace at end of line #}
first line {% if 1 > 0 %}4{% endif %}
and second line on new line
line before for
{% for i in range(1, 9) %}
{{- i -}}
{% endfor %}
new line after endfor
--DATA--
return []
--EXPECT--
first line 1
and second line on new line
first line 2
and second line on new line
first line 3
and second line on new line
first line 4
and second line on new line
line before for
123456789
new line after endfor
And output is
Test line ending (in whitespace/trim_line_ending.test)
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'first line 1\n
-and second line on new line\n
+'first line 1and second line on new line\n
\n
-first line 2\n
-and second line on new line\n
+first line 2and second line on new line\n
\n
-first line 3\n
+first line3\n
and second line on new line\n
\n
first line 4 \n
@@ @@
and second line on new line\n
\n
line before for\n
-123456789\n
-new line after endfor'
+123456789new line after endfor'
It not documented and lead to some kinds of errors. For example it can be dangerous in js:
var isFoo = {% if o.isFoo %}true{% else %}false{% endif %}
var isBar = true
And twig already uses different approaches for removing line endings after output and execution tags. In php, removing line endings is useful for a few reasons. This was discussed on the mailing list in 1998 (25 years ago!) https://marc.info/?t=90279165800002&r=1&w=2
But why does this rule about deleting a newline after closing a tag exist in Twig?
Activity
stof commentedon Apr 14, 2022
See https://twig.symfony.com/doc/3.x/templates.html#whitespace-control
pudovmaxim commentedon Apr 13, 2023
I have question about whitespace control related to this. My test scenario:
And output is
It not documented and lead to some kinds of errors. For example it can be dangerous in js:
and instead
we got a wrong js-code
pudovmaxim commentedon Apr 14, 2023
I make demo on raw php and twig
https://onlinephp.io/c/d6084
https://twigfiddle.com/9h6dsl
And twig already uses different approaches for removing line endings after output and execution tags. In php, removing line endings is useful for a few reasons. This was discussed on the mailing list in 1998 (25 years ago!) https://marc.info/?t=90279165800002&r=1&w=2
But why does this rule about deleting a newline after closing a tag exist in Twig?
stof commentedon Apr 14, 2023
This is actually documented. It is the first sentence in the documentation section that I linked to you:
pudovmaxim commentedon Apr 14, 2023
Yes, sorry about that. Misunderstood the meaning and thought about the line ending at end of template.
But the question is still open:
Why is this principle from php is used in twig? And how is it possible to disable it globally?
stof commentedon Apr 14, 2023
you cannot disable it globally.