How to output html without whitespace getting removed in twig? - php

I started to use twig as template engine and I like it somehow.
The only thing I don't know how to disable it, is the optimized html that it renders (newest version of twig).
Twig seems to remove all unused white spaces and line breaks.
In Productive Mode it is quite useful if you have a page that should have a high rank in google.
But during Development it is not really usefull.
So my question: How do you disable this?

If you use the spaceless tag twig remove whitespace between HTML tags, not whitespace within HTML tags or whitespace in plain text:
{% spaceless %}
<div>
<strong>foo</strong>
</div>
{% endspaceless %}
output will be <div><strong>foo</strong></div>
For more information on whitespace control, read the dedicated section of the documentation and learn how you can also use the whitespace control modifier on your tags.
Your twig version is 1.18.1 ?

Related

HTML Entities in Symfony Twig

I´m currently working on a code review of a friend and I found an XSS-Vulnerability I´d like to understand properly:
Lets say i I have a Variable foo.bar with the input <h1>test</h1>
I now figured out this pattern:
{{foo.bar}} -> no XSS
{% trans with { '%var%': foo.bar } %} My "%var%" {% endtrans %} -> XSS
{% trans with { '%var%': foo.bar | e('html') } %} My "%var%" {% endtrans %} -> no XSS
I thought I´ll run a Regex Pattern trough his whole code to find potential other places for bad encoding of HTML Character, but I did not quite understand when twig is encoding HTML tags and when not. I do understand the "e" (Encoding) function which decodes my variable value in html entities, but why is {{foo.bar}} encoding the characters while {% trans with ... is not?
I would search with this pattern for Coding mistakes in Twig:
Regex:
'\{%(.){0,2}[trans](.){0,2}[with].*'
-> Searching for "{%[space?]trans[space?] with"
as I guess everytime he missed the |e('html') there might be an issue. Am I on the right track? Do I miss something??
I hope i can find more clarification on this topic here :)
Twig always escapes but "trans with" is part of symfony and not twig. It is not autoescaped because it is passed to a tag, and the tag may output it but that is not a certainty so this is why they refuse to autoescape.
I personally always use the |trans() filter instead so by default you know you are safe, you can still ofcourse use |raw if needed.
https://symfony.com/doc/current/translation/templates.html
Using the translation tags or filters have the same effect, but with one subtle difference: automatic output escaping is only applied to translations using a filter. In other words, if you need to be sure that your translated message is not output escaped, you must apply the raw filter after the translation filter:

Preserve whitespace between concurent HTML elements in raw markup

I need to render raw HTML on page using twig. Issue that I'm having is that when I have two concurrent HTML element separated by white-space, that white-space gets removed.
How can I preserve that space?
I'm rendering HTML string as so:
{{ set _html = entity.html }}
{{ _html|raw }}
For example:
<p>start <span class="some-class">one</span> <span class="some-class">two</span> stop</p>
Is rendered as:
<p>start <span class="some-class">one</span><span class="some-class">two</span> stop</p>
I'm sure that twig raw function is sanitizing my data and therefore my issue.
How I see it:
As cale_b recommended, I will be using following CSS hack to add a space before element that lacks my spacing:
.monograph {
* + span:before {
content: ' ';
}
}
As answered in here and also in my case, the issue was that I had a {% spaceless %} tag that wrapped my content. So |raw was working correctly but it was the spaceless tag that was stripping the spaces.

How to include inline br tag within a translation string

Hi we're using the Twig templating system within our site along with the twig i18n extension to handle our language translations.
As per the documentation, all of our template strings are wrapped in the trans block to be translated by the extension as shown below:
{% trans "Text to be <br>translated" %}
The issue is that within some of our template strings we have inline <br> tags for text formatting. In all the instances where these <br> tags exist, the strings don't translate and remain in English. Is there any way to 'escape' the <br> tags within a trans block, so that all the strings are read and translated properly?
You can run it through a nl2br filter as well as the trans filter:
{{ "Company Name\nAll Rights Reserved."|nl2br|t }}

Can we make twig remove whitespace when it's compiled, rather than when it's rendered?

Twig has the {% spaceless %} tag, which removes all the white space between HTML tags.
However, it does this with a preg_replace when you render the template. Fine on small files, but if you have a large complex template there's a performance hit.
I feel like it should be possible to strip the whitespace out at compile time?
My compiled template is full of stuff like
echo " <h2>Heading</h2>
";
Where the template has included the following:
<section>
<h2>Heading</h2>
</section>
What I want on the final rendered HTML is
<section><h2>Heading</h2></section>
Why couldn't twig (very simply) add a trim in when building the compiled template, to give us:
echo "<h2>Heading</h2>";
in the compiled template php code.
I get that there could still be whitespace in whatever data I populate the template with inside {{ }}, but I can control that from my PHP easily.
OK, after much digging in the library trying to work out which files generate which bits of the output, I've finally found this "fix".
Change
->string($this->getAttribute('data'))
to
->string(trim(preg_replace('/>\s+</', '><', $this->getAttribute('data'))))
On line 30 of /lib/Twig/Node/Text.php.
Doing that correctly gives me a "spaceless" output, but without requiring the expensive template-render-time preg_replace call.
Will it cause problems? Possibly in some use cases, maybe with a partial <pre> or <textarea> tag. I can't see either of those being an issue for me though.
Any gotchas that I've not thought of?
Try to use trim function from Twig library
trim - Documentation - Twig - The flexible, fast, and secure PHP template engine
The right tool for your needs if the spaces are in the template source is the whitespace control feature of Twig: http://twig.sensiolabs.org/doc/templates.html#whitespace-control
If the spaces are in a variable being displayed in the output, you should use the trim filter (or trim the variable before passing it to Twig, which will do the same anyway)

What does "{% %}" syntax mean?

I'm using someones PHP file.
And it has text like:
<html>
... regular HTML
{% if (some condition){
<another regular html tag>
</another regular html tag>
}%}
</html>
And I don't get it if these {% tags %} are javascript or PHP, or something else?
thx.
It is some templating language. Most likely a server-side one, i.e. one that is based on PHP.
Looks like a template to me. The {% and %} is the templating's system of identifying where it has to do its work.
It can think of two reasons:
User might have changed "<?" to "<%"
It is a template language

Categories