My goal is having a string like "name: smoothie, ingredients: milk, orange, category: vegan" (there can be a lot option: value or option: value, value, value... pairs) to produce an array like the following
[
{
option: 'name',
value: ['smoothie']
},
{
option: 'ingredients',
value: ['milk', 'orange']
},
{
option: 'category',
value: ['vegan']
}
]
I thought something like the following would work but it produces the following error and i can't understand why.
The problem is in the line where i try to add a value to the existing options[last_ok_index].value array
{% set options[last_ok_index].value = options[last_ok_index].value|merge( [ x[0] ] ) %}
Unexpected token "punctuation" of value "[" ("end of statement block" expected).
{% set product = "name: smoothie, ingredients: milk, orange" %}
{% set options = [] %}
{% set last_ok_index = 0 %}
{% for item in product|split(',') %}
{% set x = item|split(': ') %}
{% if x|length == 2 %}
{% set options = options|merge( [ { option: x[0], value: [x[1]] } ] ) %}
{% set last_ok_index = loop.index - 1 %}
{% else %}
{% set options[last_ok_index].value = options[last_ok_index].value|merge( [ x[0] ] ) %}
{% endif%}
{% endfor %}
{# print result #}
{% for item in options %}
{{item.option }}
{% for inner_item in item.value %}
{{"-" ~ inner_item}}
{% endfor %}
{% endfor %}
You should go with the suggestion in the comments by #dbrumann and use a TwigExtension.
However if you want to solve this in pure twig, then you are overcomplicating things.
First things first, the problem already starts at your first split, your expected output is smoothie and ingredients, while the actual result will be smoothie, ingredients, orange. You can fix this by passiung asecond argument to the split filter, which will limit the output.
Split uses the PHP function explode in the background. More on what the second parameters does you can find in the documentation here
Now as I said you can simply your snippet by creating the "item" in two parts rather than one part
{% set product = "name: smoothie, ingredients: milk, orange" %}
{% set items = [] %}
{% for item in product|split(',', 2) %}
{% set tmp = item|split(':') %}
{% set option = tmp[0] %}
{% set values = [] %}
{% for value in tmp[1]|split(',') %}
{% set values = values|merge([ value, ]) %}
{% endfor %}
{% set items = items|merge([ {'option': option, 'values': values,}, ]) %}
{% endfor %}
demo
As you've changed the initial input of the original question. The problem still starts with the split filter. I'd suggest you use another delimeter for your values, e.g. ;
{% set product = 'name: smoothie 3, ingredients: milk ; orange; pineapple, category: bar' %}
{% set products = [] %}
{% for string in products_raw %}
{% set product = [] %}
{% for item in string|split(',') %}
{% set tmp = item|split(':') %}
{% set option = tmp[0] %}
{% set values = [] %}
{% for value in tmp[1]|split(';') %}
{% set values = values|merge([ value, ]) %}
{% endfor %}
{% set product = product|merge([ {'option': option, 'values': values,}, ]) %}
{% endfor %}
{% set products = products|merge([ product, ]) %}
{% endfor %}
{% for product in products %}
{% for item in product %}
- Option: {{ item.option }}
- Values:
{% for value in item.values %}
- {{value }}
{% endfor %}
{% endfor %}
----------------------------------
{% endfor %}
demo
Thank you a lot for all the tips, i changed the logic a bit and it works now.
I will search about twig extensions as you proposed since it is for sure too much code in twig for something like that.
{% set product = "name: smoothie, ingredients: milk, orange, sugar, tags: healthy, popular, category: milk" %}
{% set options = [] %}
{% set last_option = null %}
{% set last_value = null %}
{% for item in product|split(',') %}
{% set x = item|split(':') %}
{% if x|length == 2 %}
{% if last_value|length > 0 %}
{% set options = options|merge( [ {option: last_option, value: last_value} ] ) %}
{% endif %}
{% set last_option = x[0] %}
{% set last_value = [x[1]] %}
{% else %}
{% set last_value = last_value|merge([x[0]]) %}
{% endif%}
{% if loop.last %}
{% if last_value|length > 0 %}
{% set options = options|merge( [ {option: last_option, value: last_value} ] ) %}
{% endif %}
{% endif %}
{% endfor %}
{# print result #}
{% for item in options %}
{{ item.option }}
{% for inner_item in item.value %}
{{ "-" ~ inner_item }}
{% endfor %}
{% endfor %}
i have to configurate a .csv file.
I have a variable that is either a single value or an array of values. If it is a single value, i want to put that single value into the cell, otherwise i want to put every value in the array into the cell.
This is my approach, but it's not iterating through the array. If the item is an array, it just puts nothing into to table cell. Do i need to increment i in some sort of way?
{% if item is iterable %}
{% for i in item[0..10]%}
*{{ item[i] }}
{% endfor %}
{% else %}
{{item}}
{% endif %}
Not sure why are you using {% for i in item[0..10]%} to iterate the item?
0..10 returns an array in twig, which will result in the following "code"
{% for i in item[Array] %}
This will return nothing as the index Array doesn't exist in the array item.
The proper way to iterate the value would be
{% if item is iterable %}
{% for i in item %}
{{ i }}
{% endfor %}
{% else %}
{{item}}
{% endif %}
If you are trying to display only 10 values from the array u'd go with
{% for i in item[0:10]%}
{{ i }}
{% endfor %}
or
{% for i in item|slice(0, 10) %}
{{ i }}
{% endfor %}
I would like to loop on this variable that I have created before :
{% set divisionElement = (elementsLength/2)|round|number_format(0) %}
The output of this is a number.
After that I would like to create a loop with this value like that :
{% for i in divisionElement %}
{{dump(i}}
{% endfor %}
When I tried to dump i in my loop I have nothing result.
Try using range, If divisionElement is > 0
{% for i in range(1, divisionElement ) %}
{{ i }},
{% endfor %}
How do I loop multidimensional array in twig.
What I've tried is
{% for key, record in records %}
{% for key1, record1 in record %}
{{ key1 }}
{% endfor %}
{% endfor %}
But I only get the index of array like so
0
0
0
0
1
0
0
1
What I want is to get the value of MoneyChanger and AddTransaction Array. Like for example
id
name
currency
amount
pieces
I want to post my answer.
I manage to resolve the issue by
{% for key, record in records %}
{% for key1, record1 in record %}
{% if record1.client is defined %}
{{ record1.id }}
{% endif %}
{% endfor %}
{% endfor %}
I am trying to concatenate a variable to an array key to get access to certain values in Twig, but no success so far.
I have a large PHP array that has for example keys like this:
$array = [
...
...
...
'test_1' => $test_1,
'test_2' => $test_2
];
I tried the following in my Twig template:
{% for i in 1..2 %}
{% if array.test_{{ i }} != 0 %}
<div>Test</div>
{% endif %}
{% endfor %}
but that doesn't work.
Is there a way to access values like this in Twig?
Try this:
{% for i in 1..2 %}
{% if array['test_' ~ i] != 0 %}
<div>Test</div>
{% endif %}
{% endfor %}