I am accessing dynamic data from an array:
{% for key, value in columns_arr %}
{% for k,v in group %}
var {{ value }} = "{{ attribute(v, value) }}";
{% endfor %}
{% endfor %}
This is working well for name and id (see below). In the example of name the attribute ...
{{ attribute(v, value) }}
is replacing:
{{ v.name }}
and in the example of id it is replacing ...
{{ v.id }}
But this is not working with type because here I actually need to replace:
{{ v.type.name }}
So my question is, how would this look like in the attribute function?
I tried {{ attribute(v.name, value) }} but I get the error
Impossible to access an attribute ("type") on a string variable
("ID").
group:
array:4 [▼
0 => Fields {#7444 ▼
-id: 1
-name: "ID"
-unique_id: "6ab8c870ed"
-productgroup: PersistentCollection {#7448 ▶}
-type: Type {#7525 ▼
+__isInitialized__: true
-id: 2
-name: "hidden"
-unique_id: "5e1086c862"
-label: "hidden"
…2
}
}
1 => Fields {#7526 ▶}
2 => Fields {#7530 ▶}
3 => Fields {#7534 ▶}
]
columns_arr:
array:3 [▼
0 => "id"
1 => "name"
2 => "type"
]
My approach according to this question:
How to check a multidimensional Twig array for values?
{% for key, value in columns_arr %}
{% for k,v in group %}
{% for k1,v1 in v %}
var {{ value }} = "{{ attribute(name, v1) }}";
{% endfor %}
{% endfor %}
{% endfor %}
But this gives me an error, My page is not loading anymore.
Another approach is this:
{{ attribute(v, [value.name]) }}
But I get the error:
Impossible to access an attribute ("name") on a string variable
("type").
If you are able to change the column array to something like 2 => 'type.name', you can use the following snippet to read out nested data:
{% for value in data %}
{% for column in columns %}
{% set output = value %}
{% for method in column|split('.') if method != '' %}
{% set output = attribute(output, method) | default('') %}
{% endfor %}
{{ output }}
{% endfor %}
{% endfor %}
demo
Related
I wanna array my collection in 3 cols, for 3 different statuses. And if there isn't any gig/item with that status, it has to say ' No projects'
I have tried this:
<div class="col-sm">
<h2>Up next</h2>
{% assign next = site.gigs | gig.status == 'Next' | sort: gig.date %}
{% if next.gigs.size == 0 %}
No projects
{% else %}
{% for gig in next %}
{{ gig.title }}
{% endfor %}
{% endif %}
</div>
<div class="col-sm">
<h2>Working on</h2>
{% assign on = site.gigs | gig.status == 'On' | sort: gig.date %}
{% if on.gigs.size == 0 %}
No projects
{% else %}
{% for gig in on %}
{{ gig.title }}
{% endfor %}
{% endif %}
</div>
<div class="col-sm">
<h2>Done</h2>
{% assign done = site.gigs | gig.status == 'Done' | sort: gig.date %}
{% if done.gigs.size == 0 %}
No projects
{% else %}
{% for gig in done %}
{{ gig.title }}
{% endfor %}
{% endif %}
</div>
But it just arrays all of the gigs/items :(
Maybe it can be done in a way more simple way.
I don't know if you could make one compact liquid code and array 3 columns by counting the number of different statuses.
Help!
Ordering
Our statuses are "Next", "On" and "Done". They must be ordered in such order.
As this is not an alphabetical sort order, we need to define this order by ourself.
In _config.yml :
status-order:
-
name: "Next" ### status as it is set on gigs (!!! Case-Sensitive !!!)
display: "Up Next" ### status column header to display
-
name: "On"
display: "Working On"
-
name: "Done"
display: "Done"
We can now loop over site.status-order and get our gigs in desired status order.
{% for status in site.status-order %}
{{ status.name }} - {{ status.display }}
{% endfor %}
Presenting
As your current code is a little repetitive, we can factor it like this :
{% for status in site.status-order %}
{% assign items = site.gigs | where: 'status', status.name | sort: date %}
<div class="col-sm">
<h2>{{ status.display }} ({{ items.size }})</h2>
{% if items.size > 0 %}
<ul>
{% for item in items %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{% else %}
No project
{% endif %}
</div>
{% endfor %}
Note
You must be sure to set status with the right case (eg : "Next" an not "next").
And the right type. If you set status: On it is understood as the true boolean value, not the string "on". In this case the correct status expression is status: "On". It must be quoted or double quoted to be understood as "On" string.
Any item with incorrectly cased or typed status expression will not appear in our listing.
My controller sends to Twig the following associative array in a variable called 'petition';
Array
(
[0] => stdClass Object
(
[id] => 1
[doctype] => "somedoc"
[nrdoc] => "99"
[datadoc] => "2015-01-01"
)
[1] => stdClass Object
(
[id] => 2
[doctype] => "otherdoc"
[nrdoc] => "100"
[datadoc] => "2015-01-01"
)
)
Then, in my Twig template (view) I'm doing this:
{% for id in petition %}
{% if id.doctype == 'somedoc' %}
{{id.nrdoc}} / {{id.datadoc}}
{% else %}
UNDEFINED!
{% endif %}
{% endfor %}
The problem is that I can't figure out the logic of how to output "UNDEFINED!" only once, if the doctype != "somedoc" when there are other key->value elements in the array. The way I'm doing it, it will output "UNDEFINED!" everytime the script loops...
Thank you in advance for your help
Gabriel
One variant is to define an extra variable for this:
{% set undefined = false %}
{% for id in petition %}
{% if id.doctype == 'somedoc' %}
{{ id.nrdoc }} / {{ id.datadoc }}
{% else %}
{% set undefined = false %}
{% endif %}
{% endfor %}
{% if undefined == true %}
UNDEFINED!
{% endif %}
You can read more about setting Twig variables here.
I want to list all my posts within site.categories.projects as a comma separated sentence. There's documentation for displaying {{ site.tags }} as array_to_sentence_string but how can I use the filter with a for loop?
# empty array
{% assign postsTitlesArray = '' | split:':' %}
# pushing categorie posts title in our array
{% for post in site.categories.one %}
{% assign postsTitlesArray = postsTitlesArray | push: post.title %}
{% endfor %}
{{ postsTitlesArray | array_to_sentence_string }}
I want to show my string value into my array 'nameComments' with key {{loop.index}} of my comments array, but {{ nameComments[{{ loop.index }}] }} show an error
{% for com in comments %}
<p>Comment {{ nameComments[{{ loop.index }}] }} : "{{ com['comment'] }}"</p>
{% endfor %}
If I try:
{% for com in comments %}
<p>Comment {{ nameComments[1] }} : "{{ com['comment'] }}"</p>
{% endfor %}
And the {{ loop.index }} show me value : 1
So how can I implement my loop index into my array?
{% for com in comments %}
<p>Comment {{ nameComments[ loop.index ] }} : "{{ com['comment'] }}"</p>
{% endfor %}
Just leave out the curly brackets. This should work fine.
By the way loop.index is 1 indexed. If you loop through an array which normally starts with index 0 you should consider using loop.index0
See the documentation
It is safer to iterate over the real value of the array index and not using loop.index and loop.index0 in case where array indexes do not start in 1 or 0 or do not follow a sequence, or they are not integers.
To do so, just try this:
{% for key,com in comments %}
<p>Comment {{ nameComments[key] }} : "{{ com['comment'] }}"</p>
{% endfor %}
See the documentation
Let's say I have this kind of arrays :
<?php
$monsterOne['statistics'] = array('attack' => 15, 'defense' => 20, 'speed' => 5);
$monsterTwo['statistics'] = array('attack' => 10, 'defense' => 0, 'speed' => 7);
And I want to display, via twig :
monsterOne : 15 en Attaque, 20 en Défense, 5 en Vitesse
monsterTwo : 10 en Attaque, 7 en Vitesse
How can I achieve this ?
I tried this, and it worked, but the commas between each statistic are not present.
{% if statistics.attack is defined %} {{statistics.attack}} {{"en Attaque" | trans}} {% endif %}
{% if statistics.defense is defined %} {{statistics.defense}} {{"en Défense" | trans}} {% endif %}
{% if statistics.escape is defined %} {{statistics.escape}} {{"en Vitesse" | trans}} {% endif %}
I think that I should use something like this, but I don't know how to put the translation inside :
{{ statistics|join(', ') }}
I found the answer. The trick was to parse the array via a loop and use loop.last :
{% for statistic, value in statistics %}
{% if statistic == 'attack' %} {{ value }} {{ 'en Attaque' | trans }}{% endif %}
{% if statistic == 'defense' %} {{ value }} {{ 'en Defense' | trans }}{% endif %}
{% if statistic == 'speed' %} {{ value }} {{ 'en Vitesse' | trans }}{% endif %}
{% if loop.last == false %}, {% endif %}
{% endfor %}">