Strange Twig behaviour when using "in" operator - twig

Today I noticed strange behaviour then trying to check if array has value.
I tried to do {% if key in array|keys %} ... {% endif %}
and condition was equal to true always.
I tried to do this later: {{ dump('a' in [0, 1, 2]) }}.
And guess what value was dumped? It was "true" somehow.
Do you guys have any idea why is it happening?
I can workaround it by using 'a' in [0, 1, 2]|join but that's not what I want to figure out.

It's not twig, it's php. The following code:
var_dump(in_array('a', array(0, 1, 2)));
prints:
bool(true)
When comparing a string to an int, the string gets converted to int. In this case, 'a' becomes 0, thus matching one of the array keys.
Try doing a var_dump("foobar" == 0) and you'll see it is true as well.
You can use foo['a'] is defined instead, demo here: http://twigfiddle.com/y126mg

Related

Parametrized twig date

I need how to check if a custom date is inside a range.
The problem is that the API returns a calendar but year and month are sent separately and I can't create a date with twig.
This part of the code seems to return my variables as expected
<script>console.log("Year"+{{CurrYear| json_encode()| raw}});</script>
<script>console.log("Month: "+{{CurrMonth| json_encode()| raw}});</script>
while I can retrieve the day within the loop
<script>console.log("Day: "+{{key| json_encode()| raw}});</script>
I'm trying to create a data item so I can use the native comparisons. I know I can split the other date and compare it one by one, but I'm trying to avoid this
<script>console.log({{ annoForm."-".mesForm."-".key |date('Y-m-d')}}) ;</script>
So I can use it afterwards like
{% set auxDate = annoForm."-".mesForm."-".key |date('Y-m-d') %}
BUT, I can't seem to construct a valid date here so I could use it in:
{% datestart < auxDate and dateend > auxDate %}
{# condition met #}
{% endif %}
Main problem here was concatenating correctly the string when instantiating date():
{% set auxDate = ("#{annoForm}-#{mesForm}-#{key} " | date('Y-m-d') ) %}
I want to add a couple of issues i found while working on this.
First the importance of using date('Y-m-d') instead of "date()" because it will consider July before June (due alphabetic order).
Take nulls or open fields into account (in my case datestart is mandatory)
{% if datestart < auxDate and ( dateend is null or dateend > auxDate ) %}
Hope it helps!

How to define "ends with any two letters after underscore" in Twig

In the following example, this condition includes all type elements of an array that do not include _.
{% for type in array %}
{% if '_' not in type) %}
Instead, I would like to include all elements that do not end with _any2letters, where "any2letters" is actual any 2 letters. I examined Twig documentation and wasn't able to find the required syntax.
It was solved using:
{% if not (type matches '/_[a-z]{2}$/') %}
This solution takes advantage of PHP regex syntax.
"/" are used in Twig to define borders of regular expressions.
"_" is my underscore as is; [a-z]{2} means "2 lowercase letters".
And finally $ means that the preceding symbols are in the end of the
string.

Twig RAW filter on literal string not working

{{ (vendorData.description) ? vendorData.description : "<em>No Description Entered</em>"|raw }}
When the value is not present I see:
<em>No Description Entered</em>
Printed literally on the screen in the web browser.
Raw should force the characters to be literal, not > < etc.
Why does this not work on a "created string" but if I do it on a string variable it works?
You need to place brackets around the whole statement like so:
{{ ((vendorData)
? vendorData
: "<em>No Description Entered</em>")|raw }}
Here is a working twigfiddle to show it working:
https://twigfiddle.com/fs2oc2
You can use twigfiddle to experiment with your code.
From feedback in comments section:
here is a twig example to show what you need: https://twigfiddle.com/hjyslr

Check if string variable is null or empty, or full of white spaces

How can I check if a string variable is null or empty, or full with space characters in Twig? (Shortest possible, maybe an equivalent to CSharp's String.IsNullOrWhiteSpace() method)
{% if your_variable is null or your_variable is empty %}
should check whether the variable is null or empty.
If you want to see if it's not null or empty just use the notoperator.
{% if foo is not null and foo is not empty %}
See the docs:
empty
null
"is" operator
logical operators like "not"
Perhaps you might be interested in tests in twig generally.
There are already good answers, but I give my 2 cents too:
{% if foo|length %}
I was inspired by #GuillermoGutiƩrrez's filter trick.
But I think |length is safer as the "0"|trim expression will evaluates to false.
References :
length
codepad
boolval
I'd rather use just trim and empty:
{% if foo|trim is empty %}
{% if foo|trim is not empty %}
empty evaluates to true if the foo variable is:
null
false
empty array
empty string
{% if foo|trim %} seems to be enough (assuming that foo is the variable to check). If foo is not null, trim removes whitespaces. Also, if handles empty string or null as false, and true otherwise, so no more is required.
References:
trim

Coding Implode In Twig

How can one use the equivalent of the implode function in a Twig environment?
For example, the contents of the variable $data1 = "input your name" and the variable $data2 = "input your address".
How to create a variable $result = "input your name, input your address" in Twig?
I'm guessing you're looking for the join filter. It works exactly like implode does in php. Quoting from the manual page:
The join filter returns a string which is the concatenation of the items of a sequence:
{{ [1, 2, 3]|join }}
{# returns 123 #}
The separator between elements is an empty string per default, but you can define it with the optional first parameter:
{{ [1, 2, 3]|join('|') }}
{# returns 1|2|3 #}

Resources