Twig negate starts with - twig

What is the negation of starts with in twig templates ?
I get variabe with url like "account" and dont want to display login button if my url starts with "account".
What is the nagation of starts with in my case ?
{% if req starts with 'account' %}
login
{% endif %}

You can negate the expression with not. In order this to work with start withs u'd need to force twig to execute the expression first with parantheses.
{% if not (req starts with 'account') %}
login
{% endif %}
demo

Related

Check if all elements in one array are contained by another | JS Array.every() equivalent

I'm looping over a collection of blog posts (Twig for loop) which appearance depends on tags given.
Here a quick example: I want to display all blog posts that have the tags "foo" and "bar".
It seems pretty easy to check if a post has one of the tags.
However it seems that checking if both tags are contained by a blog post isn't trivial.
What I want to accomplish is what the array.every() method in javascript does.
That's my current solution which works as expected but feels kinda fiddly and overcomplicated:
{% set given_tags_array = data.tags|split(',') %}
{% for post in posts %}
{% set post_categories_array = post.categories|map(category => category.name) %}
{% set bool_buffer_array = [] %}
{# push comparison result in bool array #}
{% for tag in given_tags_array %}
{% set bool_buffer_array = bool_buffer_array|merge([tag in post_categories_array]) %}
{% endfor %}
{# only display posts where all tags match #}
{% if false in bool_buffer_array %}
{% else %}
{# post data goes here #}
{% endif %}
{% endfor %}
As you can see inside the posts loop I'm checking if every given tag (i.e. "foo" and "bar") is part of the post categories array. I'm pushing the comparison result (boolean) to an empty array to check for any false values afterwards.
Why an array? I tried using a simple boolean variable but if any of the given tags is in the post categories array it resolves to true, which isn't exactly what I want.
So something like that doesn't work for me unfortunately:
{% for post in posts %}
{% set post_categories_array = post.categories|map(category => category.name)|sort|join('') %}
{% if given_tags_array|filter(given_tag => given_tag in post_categories_array) %}
{# post data goes here #}
{% endif %}
{% endfor %}
With this method I'm always doing an or comparison instead of an and comparison...
So...am I missing something and is there a simpler way to do that twig only?
Using the code you've already provided:
{% set temp = given_tags_array|filter(given_tag => given_tag in post_categories_array) %}
The filter filter returns a new array, this means temp should contain as many elements as your given_tags_array, if they are all inside the post_categories_array.
So if I'm not mistaken you could change your check to the following
{% for post in posts %}
{% set post_categories_array = post.categories|map(category => category.name)|sort|join('') %}
{% set temp = given_tags_array|filter(given_tag => given_tag in post_categories_array) %}
{% if temp|length == given_tags_array|length %}
{# display post #}
{% endif %}
{% endfor %}

If statement with string length check

I'm trying to check if a string is empty in a twig template but I don't understand this behaviour. I want to show a textarea element when the condition is met. Here's the code:
{% if item.payload.customizationText|length == 0 %}
<textarea class="customization-text">{{ item.payload.customizationText|trim }}</textarea>
{% endif %}
It always shows the textarea, whether the string has something in it or not. Am I missing something?
It's in shopware 6 by the way and the dump() fuction throws an error because it's undefined.
Also, this expression just outputs the string. Is the length expression not available?
{{ item.payload.customizationText|length }}
I believe there is a mistake in the question. It does not make sense to print the variable, only if it is empty.
If you want to show the text area in case the customizationText has some contents, you should use this:
{% if item.payload.customizationText|trim|length %}
<textarea class="customization-text">{{ item.payload.customizationText|trim }}</textarea>
{% endif %}
https://twigfiddle.com/nmk2kq/4
You can try it.
{% if item.payload.customizationText is defined and item.payload.customizationText is empty %}
<textarea class="customization-text">{{ item.payload.customizationText|trim }}</textarea>
{% endif %}

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".

Symfony, Twig, if conditions for tab highlights according to current route

I am trying to get a list to highlight if it is at its current page (route). However, I also have subpages within the pages of which I also want the list to be highlighted.
I have my menu if statements:
<ul class="menu">
{% if app.request.get('_route') == 'home' %}
<li class="current">Home</li>
{% else %}
<li>Home</li>
{% endif %}
{% if app.request.get('_route') == 'reports' %}
<li class="current">Reports</li>
{% else %}
<li>Reports</li>
{% endif %}
// etc etc
Now in my reports page, the route is /reports/ I have a menu that clicks to "Detail", "Summary", etc it will go to /reports/detail and /reports/summary... I want it so that when users click on those links, the main navigation is still highlighted.
I was wondering if there is an if statement condition something like this:
{% if app.request.get('_route') starts with(?) 'reports' %}
So whenever anyone goes to a route that's a sub page of /reports/, the "Reports" li in the menu will still be highlighted?
I'm not sure if twig has a function for "starts with" but you can check for containment using in
{% if 'reports' in app.request.get('_route') %}
Just to update this question with current information.
As per current (2.x) Twig documentation this is possible the way it is asked for.
To be more specific, the documentation states:
You can also check if a string starts with or ends with another string:
{% if 'Fabien' starts with 'F' %}
{% endif %}
{% if 'Fabien' ends with 'n' %}
{% endif %}
As such, the desired expression is perfectly possible:
{% if app.request.get('_route') starts with 'reports' %}
And works as expected.
There are some good choices on this thread but another option is to pass the route into an array. This is useful if you have dropdown menu items.
The items in the array would be your defined routes.
{% set routes = {
'activities':
[
'walking',
'swimming',
'running'
]
} %}
Then in your menu bar add this to your menu label class.
{% if app.request.attributes.get('_route') in routes.activities %} Do Something {% endif %}

Symfony 2 render controller in twig and assign it to variable

I have a Symfony 2.1 version with a controller that returns the total of points.
I am rendering this in my twig template as follows:
{%render "AdminBundle:Reports:getExpiringPoints" with {'id':dealer.id}%}
This prints the total points. I need to check that value and print it if the rendering value is greater that 0.
Is it possible in Symfony 2.1?
i found that :
{% set x %}
{%render "AdminBundle:Reports:getExpiringPoints" with {'id':dealer.id}%}
{% endset %}
{% if x> 0 %}
//display
{% endif %}
and after you can use it.
Tell me if it works
You can check it directly in the controller or with twig :
{% if var > 0 %}
//display
{% endif %}
Twig supports all of the standard logical operators ==, !=, <, >, >=, and <=.

Resources