Looping through a limited number of elements inside an array - php

I have an array of users, how can I make a limited number of iterations using twig.
I have 5 elements inside the array, and i only need to loop through 4 of them.
instead of doing like this:
for user in users
user
endfor
it would be something like this
for ... in 0..3
user
endfor

You can use the slice filter
{% for user in users|slice(0,4) %}
...
{% endfor %}
You can even use the twig shortcut
{% for user in users[0:4] %}
...
{% endfor %}

You can use Twig extension Slice
In example :
{% for user in users|slice(0, -1) %}
...
{% endfor %}
slice(0, -1) means you start from 0 and end to last element - 1

Related

Test existence of a macro in Twig 2

I need to be able to test the existence of a macro in Twig and to call it dynamically.
Here is what I tried:
{% macro test(value) %}
Value: {{ value }}
{% endmacro %}
{% import "_macros.html.twig" as macro %}
{{ attribute(macro, 'test', ['foo']) }}
But I get this error: Accessing Twig_Template attributes is forbidden.
Regards,
Since Twig 1.20.0, template attributes are not available anymore for security reasons, so there are no native way to do it properly.
You can eventually use the source function to get macro's source file and parse it to check if a macro exists, but that's a kind of ugly hack easy to bypass.
Example:
main.twig
{% import 'macros.twig' as macros %}
{% set sourceMacros = source(macros) %}
foo {% if 'foo()' in sourceMacros %} exists {% else %} does not exist {% endif %}
bar {% if 'bar()' in sourceMacros %} exists {% else %} does not exist {% endif %}
macros.twig
{% macro foo() %}
Hello, world!
{% endmacro %}
See this example live
Another approach would be to create a custom test to do the job.

How to automatically check if variables are not empty in Symfony 3?

(Sorry for this bad english)
I would like to know if it's possible to automatically check if variables from MySQL request are not empty in Symfony 3. I know that I can put {% if foo is defined %} in Twig or something like this but I didn't find if there's a way to do it automatically. I can test the request in the controller too. But with those solutions I have to do it for every request.
All my website uses "if not empty then show it" that's why I'm trying to find it.
Edit : I know how to check every fields of every request in Twig or in php (Controller) one by one but there is a lot of duplication code, which is "boring". Thats why I am asking you if something automatic exists to check my data. (parameter in Symfony, ...)
Thank you <3
If I understand, your problem :
You want to iterate on each property in an entity. But you can't, then you are searching for a solution to not write :
{% if entity.property1 %}
{{ entity.property1 }}
{% endif %}
{% if entity.property2 %}
{{ entity.property2 }}
{% endif %}
{% if entity.property3 %}
{{ entity.property3 }}
{% endif %}
You have two solutions to make your properties traversable :
Get your entity with a Doctrine query using ->getArrayResult() instead of ->getResult()
Use ReflectionClass to get the properties as an array :
http://php.net/manual/fr/class.reflectionclass.php
So you can iterate on each property, and do something like that :
{# Where you get your entity as an array #}
{% for property in entity %}
{% if not property is null %}
{{ property }}
{% endif %}
{% endfor %}
{# where fields comes from the ReflectionClass #}
{% for field in fields %}
{% if not attribute(entity,field) is null %}
{{ attribute(entity,field)}}
{% endif %}
{% endfor %}
Use the Twig strict_variables config parameter and set it to false (should be the default value):
strict_variables boolean
If set to false, Twig will silently ignore invalid variables
(variables and or attributes/methods that do not exist) and replace
them with a null value. When set to true, Twig throws an exception
instead (default to false).

How to check whether array element is defined or not in twig file?

I am trying to access array but it is not getting accessed.
in my config.yml following is my array :
abc : [xyz]
and in another file i am writing following code to access abc array.
{% if abc[0] is defined) %}
then do something
{% endif %}
but somehow its not working. please help me out i am newbie in this.
It depends if the variable is always declared or not:
If the variable is always declared and the array can be empty
{% if abc is not empty %}
{# then do something #}
{% endif %}
<variable> is not empty in Twig is equivalent to !empty($variable) in PHP. When an array is provided, is not empty will check there is a value and/or a value in the array.
empty test in Twig documentation.
If the variable is not always declared
Check that the abc variable is declared and not empty:
{% if (abc is declared) and (abc is not empty) %}
{# then do something #}
{% endif %}
<variable> is declared in Twig is equivalent to isset($variable) in PHP.
defined test in Twig documentation.
Based on comments I would recommend using foreach loop instead and define your ifs based on index values. Something like this:
{% for abcs in abc %}
{% if (loop.index == 0) %}
then do something
{% endif %}
{% endfor %}
BR's

Twig trans_default_domain set by dynamic value (i.e. concatenated strings/variables)

The following example is working as expected following the manual (http://symfony.com/doc/current/book/translation.html#twig-templates):
{% trans_default_domain "app" %}
However, I would like to add a dynamic value and/or an variable into "app". I tried the following examples but neither one of them are working:
{% set param = 1 %}
{% trans_default_domain "app_"~param %}
Or this:
{% set param = 1 %}
{% trans_default_domain "app_{param}" %}
Or even this does not work:
{% set custom_domain = "app" %}
{% trans_default_domain custom_domain %}
Or this:
{% trans_default_domain "custom_"~"domain" %}
I tried to search the net for this problem, but can't find any similar problems.
It looks like the trans_default_domain is not working with any dynamically generated values. Is this even possible?
Thanks in advance!

TWIG with double loop

I have a problem with show the value from variables. For example, i have function for choose columns which i want to render. I sent the 2 variables for TWIG schema to show. First is variable which stores all data from some table (e.g. user) and second for stored columns which we choosed from this tables to show. Now in the twig and want to do two loops, for show next entity and show columns from entity. The better explanation is below example but this is not working.
{% for user in users %}
{% for column in columnts%}
<li>{{ user.column}}</li>
{% endfor %}
{% endfor %}
Somebody know how can i solve this ?
Try something like that:
{% for user in users %}
{% for column in columns %}
{% if attribute(user, column) is defined %}
<li>{{ attribute(user, column) }}</li>
// or attribute(user, 'get' ~ column|capitalize) if you have getters for your properties
{% endif %}
{% endfor %}
{% endfor %}
What about using the attribute twig helper, which is commonly used to access any dynamic attribute of a given variable.
{% for user in users %}
{% for column in columns %}
<li>{{ attribute(user, column) }}</li>
{% endfor %}
{% endfor %}
Also, "attribute(user, column) is defined" should help you check for the existence of your dynamic attribute/method.

Categories