I've found it weird to notice that assembling data-attributes as string and placing it on html node results in attribute value double quoted.
If i leave it unquoted:
{% set dataId = '' %}
{% if id is defined %}
{% set dataId = ' ' ~ 'data-id=' ~ id %}
{% endif %}
and put on html node:
<div class="testDiv"{{ dataId }}>
then the data-attribute is correctly quoted.
Is this reliable behavior of twig? Why does it work that way?
It turned out that the browser was fixing quotes for me. To be able to output parameters properly, one haz to:
Include quotes in the string:
{% set dataId = ' ' ~ 'data-id="' ~ id ~ '"' %}
And use raw filter to prevent escaping quote characters:
<div class="testDiv"{{ dataId | raw }}>
Related
It seems easy, but I encounter a weird behavior.
In a twig file :
{% set my_html = 'Hello world' %}
{{- true is not same as(false) ? (true is same as(false) ? ('1'~my_html)|raw : ('2'~my_html)|raw) -}}
The printed part is ('2'~my_html)|raw and it works fine : I see a real link.
Output is :
2Hello world
Now, it works only because I apply the raw filter to ('1'~my_html)... Try this :
{% set my_html = 'Hello world' %}
{{- true is not same as(false) ? (true is same as(false) ? ('1'~my_html) : ('2'~my_html)|raw) -}}
And it will display : 2Hello world
I don't understand why I need to apply a filter on something else to get the expected result ? Is it a bug ?
This is a documented behavior of the raw filter. I quote the note from that page:
Be careful when using the raw filter inside expressions:
{% autoescape %}
{% set hello = '<strong>Hello</strong>' %}
{% set hola = '<strong>Hola</strong>' %}
{{ false ? '<strong>Hola</strong>' : hello|raw }}
does not render the same as
{{ false ? hola : hello|raw }}
but renders the same as
{{ (false ? hola : hello)|raw }} {% endautoescape %}
The first ternary statement is not escaped: hello is marked as being
safe and Twig does not escape static values (see escape). In the
second ternary statement, even if hello is marked as safe, hola
remains unsafe and so is the whole expression. The third ternary
statement is marked as safe and the result is not escaped.
And a comment on a github issue clarifies that the concatenation operator marks your string as unsafe. So in your case
{% set my_html = '<' %}
{# ('1'~my_html) is not safe, so the whole expression is not #}
{{ false
? ('1'~my_html)
: ('2'~my_html)|raw
}}
includes two strings: a safe one, ('2'~my_html)|raw) and an unsafe one, ('1'~my_html) (because it does not apply the raw filter), so as the note from raw documentation says, the whole expression stays unsafe and autoescaping is applied. But in the other case when both strings are marked safe, the whole expression becomes safe and the autoesaping is not applied:
{% set my_html = '<' %}
{# now both strings are safe, so is the whole expression #}
{{ false
? ('1'~my_html)|raw
: ('2'~my_html)|raw
}}
This is not a bug but, due to the fact the default settings of twig will autoescape variables.
You can read more about it in the documentation.
I've just begun learning Twig and i'm really stuck at this stupid little issue. Concatenating this doesn't seem to work (eigenKleurInput will ultimately be a value):
{% set eigenKleurInput = "acefbf" %}
{% set customBackgroundColorInline = 'style=background-color: #' ~ eigenKleurInput %}
The output variable "customBackgroundColorInline" is put inside a div:
<section {{ customBackgroundColorInline }}>
Desired output would be
<section style="background-color: #xxx">
Thank you very much!
If I correctly understand your question the problem is about encoded character: if you add the " in your code twig render as ".
In this case you should use the raw filter as follow:
{% set eigenKleurInput = "acefbf" %}
{% set customBackgroundColorInline = 'style="background-color: #' ~ eigenKleurInput ~ '"' %}
<section {{ customBackgroundColorInline|raw }}>
So the output will be:
<section style="background-color: #acefbf">
You could try online in this working twigfiddle
Hope this help
Is it possible to use ternary operator in Twig when concatenating one string to another if some condition is true?
This works for me:
{% set a = 'initial' %}
{% if foo == bar %}
{% set a = a ~ ' concatenate' %}
{% endif %}
<p>{{ a }}</p>
But when I try to simplify it like this, it throws an error:
{% set a = 'initial' ~ (foo == bar) ? ' concatenate' : '' %}
<p>{{ a }}</p>
Am I doing something wrong or this simplification is simply not possible in Twig?
due to the order of precedence you'll need to add parentheses, {% set a = 'initial' ~ ((foo == bar) ? ' concatenate' : '') %}
If the 2nd part is empty you can even omit it e.g.
{% set b = 'initial' ~ ((foo == foo) ? ' concatenate') %}
twigfiddle
What's the difference between this:
{%block body %}
and that
{%block body -%}
Just read something about it in the documentation, not sure if this will also apply on {% block ... %} tags.
Twig whitespace control
{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
{{- value -}}
{%- endif -%}
{# output 'no spaces' #}
There's also another example given which trims the whitespace in front of the variable but doesnt't do it at the end - so the effect is only on one side.
{% set value = 'no spaces' %}
<li> {{- value }} </li>
{# outputs '<li>no spaces </li>' #}
The above sample shows the default whitespace control modifier, and how you can use it to remove whitespace around tags. Trimming space will consume all whitespace for that side of the tag. It is possible to use whitespace trimming on one side of a tag
So I think the difference in your given exmaples is that in the first block body there will be a whitespace after the block started. In your second example body - there's none after the block started.
Just read the documentation entry to see how it works.
EDIT
A simple example to demonstrate the example in the docu:
{% set value = 'NO space in source code after/before "value"' %}
<li> {{- value -}} </li>
...
outputs in Firebug in the HTML markup:
Whereas this
{% set value = 'space in source code after "value"' %}
<li> {{- value }} </li>
...
ouputs:
Notice the space between "value" and the closing </li> in the second example. So the minus - erases/trims a whitespace either before, after or on both sides of e.g. a variable.
How would you append more data to the same variable in Twig? For example, this is what I'm trying to do in Twig:
var data = "foo";
data += 'bar';
I have figured out that ~ appends strings together in Twig. When I try {% set data ~ 'foo' %} I get an error in Twig.
The ~ operator does not perform assignment, which is the likely cause of the error.
Instead, you need to assign the appended string back to the variable:
{% set data = data ~ 'foo' %}
See also: How to combine two string in twig?
Displaying dynamically in twig
{% for Resp in test.TestRespuestasA %}
{% set name = "preg_A_" ~ Resp.id %}
{% set name_aux = "preg_A_comentario" ~ Resp.id %}
<li>{{ form_row(attribute(form, name)) }}</li>
{% endfor %}
You can also define a custom filter like Liquid's |append filter in your Twig instance which does the same thing.
$loader = new Twig_Loader_Filesystem('./path/to/views/dir');
$twig = new Twig_Environment($loader);
...
...
$twig->addFilter(new Twig_SimpleFilter('append', function($val, $append) {
return $val . $append;
}));
Resulting in the following markup:
{% set pants = 'I\'m wearing stretchy pants!' %}
{% set part2 = ' and they\'re friggin\' comfy!' %}
{% set pants = pants|append(part2) %}
{{ pants }}
{# result: I'm wearing stretchy pants! and they're friggin' comfy! #}
IMHO I find the above sample more intuitive than the ~ combinator, especially when working on a shared codebase where people new to the syntax might get a bit mixed up.