Ternary concatenation in Twig - twig

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

Related

What does Twig's 'default' filter do if no argument is provided?

I understand how the default filter would behave if it were used like so: items|default(posts)
However, I stumbled across some code where it was used but no arg was passed:
{% if ( posts|default ) %}
{% endif %}
It's possible that it's actually not doing anything and is just incomplete or boilerplate code, but I wanted to double-check.
Not passing any arguments the default filter will result in twig returning an empty string (''). It's also worth to mention that in twig, if you test an empty string it will result in false.
So in this case if the post variable is not defined, false or an empty string, the filter will return an empty string and the if will return the value false thus ignoring the code inside the code block
{% set foo = bar|default %}
{{ foo == '' ? 'empty string' : 'not an empty string' }}
{% if '' %}
Do something
{% else %}
Don't do anything
{% endif %}
--------------------------------
{% set var1 = false %}
{% set var2 = {} %}
{% if var1 | default %}
Do sthing with var1
{% else %}
Don't do anything with var1
{% endif %}
{% if var2 | default %}
Do sthing with var2
{% else %}
Don't do anything with var2
{% endif %}
{% if var3 | default %}
Do sthing with var3
{% else %}
Don't do anything with var3
{% endif %}
demo

Access variable inside a loop and variable in Twig

I would like to do the following:
{% for i in 0..10 %}
{% if content_{{ i }}_raw == 2 %}
...
{% endif %}
{% endfor %}
Is it possible to get {{ i }} inside the variable content_1_raw and replace the 1 with the value of i?
Yes. The _context variable holds all variables in the current context. You can access its values with the bracket notation or using the attribute function:
{% for i in 0..10 %}
{% if _context['content_' ~ i ~ '_raw'] == 2 %}
...
{% endif %}
{# or #}
{% if attribute(_context, 'content_' ~ i ~ '_raw') == 2 %}
...
{% endif %}
{% endfor %}
I have written more details about this here: Symfony2 - How to access dynamic variable names in twig
Also, instead of writing 'content_' ~ i ~ '_raw' (tilde, ~, is string concatenation operator), you can also use string interpolation:
"content_#{i}_raw"

How to use Twig_Markup object type in an If statement

I want to reuse pretty heavy logic only code a few times, in php I would use a function, but in twig I went with a solution from this old question.
In short, I use a macro like that:
{% import _self as test %}
{% macro check() %}
{{ test }}
{% endmacro %}
{% set v = test.check() %}
{% if v == 'test' %}
this should display
{% endif %}
Here is a fiddle: https://twigfiddle.com/kyv3zr/2
The problem is that v is a Twig_markup object. It doesn't seem to have any public properties. Running dump on it gives me this:
object(Twig_Markup)#1244 (2) { ["content":protected]=> string(13) " 1 " ["charset":protected]=> string(5) "UTF-8" }
How do I use it in an if statement?
Or is there a better way of storing a logic only code for reuse across templates?
If the object is called v then the dump seems to show it has a content value, so try:
{% if v.content == '1' %}
{# do something here #}
{% endif %}
not certain though, but try it.
EDIT #2 - based on comments question.
So I guess if you want to use v in an if statement, you would use it like so:
{% if v == '1' %}
{# do something here #}
{% endif %}
This presumes it does equal to "1".

Twig - Append string data to same 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.

IF a == true OR b == true statement

I can't find a way to have TWIG interpret the following conditional statement:
{% if a == true or b == true %}
do stuff
{% endif %}
Am I missing something or it's not possible?
check this Twig Reference.
You can do it that simple:
{% if (a or b) %}
...
{% endif %}
Comparison expressions should each be in their own brackets:
{% if (a == 'foo') or (b == 'bar') %}
...
{% endif %}
Alternative if you are inspecting a single variable and a number of possible values:
{% if a in ['foo', 'bar', 'qux'] %}
...
{% endif %}

Resources