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.
Related
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
[![enter image description here][1]][1]My job Is too simple i.e just to add Amazon url in a div block in product thumbnail.liquid.I Have added just simple div, then I found that same div is repeated twice. I have also checked that there is no forloop found still how does it is repeating .Today I found the file called product-loop.liquid which has for loop and product thumbnail.liquid is included. What I need to do if I need to show amazon link block only once? Entire file is in gist link.Thanks.
product-loop.liquid
{% assign product_found = false %}
{% assign skip = false %}
{% assign collection_group = products | map: 'id' %}
{% assign collection_group_thumb = collection_group | append : 'thumb' %}
{% assign collection_group_mobile = collection_group | append : 'mobile' %}
{% capture new_row %}
<br class="clear product_clear" />
{% endcapture %}
<div itemtype="http://schema.org/ItemList" class="products">
{% for product in products limit: limit %}
{% if product.id == skip_product.id or skip == true %}
{% assign product_found = true %}
{% else %}
{% if forloop.rindex0 == 0 and product_found == false and forloop.length != products.count and template != 'search' %}
{% assign skip = true %}
{% else %}
{% include 'product-thumbnail', sidebar: sidebar %}
{% if products_per_row == 2 %}
{% cycle collection_group: '', new_row %}
{% elsif products_per_row == 3 %}
{% cycle collection_group: '', '', new_row %}
{% elsif products_per_row == 4 %}
{% cycle collection_group: '', '', '', new_row %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
</div>
may be you including product.thumbnail in a section and that section have loop or conditional logics.
I'm having trouble to check if a value is present in an array with Twig.
I want to hide a shipping method in a checkout if there's a certain product in the cart.
I can only use Twig code so I have to find a logic in that.
So let's say when product ID 1234 is in cart then I want to hide #certain_div
So what I have is this ->
{% if checkout %}
{% set array = theme.sku_shipping_rule | split(',') %}
// theme.sku_shipping_rule = a text string like 1234, 4321, 5478
{% if checkout.products %}
{% for product in checkout.products %}
{% if product.sku in array %}
<style>
#certain_div {
display: none;
}
</style>
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
The problem I'm facing is that it seems my code always returns true. So even if the product.sku doens't match a value in the array it still hides #certain_div. I've tested that with placing {{ product.sku }} just before <style>.
What do I wrong?
Any help greatly appreciated!
UPDATE:
I've updated the question/code to show what's happening
{% if checkout %}
{% set skuToCheck = theme.sku_shipping_rule | split(',') %}
{% set skuInCart = [] %}
{% if checkout.quote.products %}
{% for product in checkout.quote.products %}
{% set skuInCart = skuInCart | merge([product.sku]) %}
{% endfor %}
{% endif %}
{% for myVar in skuInCart %}
{{ myVar }}<br/>
{% endfor %}
// this prints
PSYGA1 // where this sku should NOT match
FP32MA4
{% for myVar in skuToCheck %}
{{ myVar }}<br/>
// this prints
FP32LY4
FP32STR4
FP32MA4
{% if myVar in skuInCart %} // also tried with | keys filter
{{ myVar }} is found
{% endif %}
{% endfor %}
{% endif %}
So what I did is placing the sku's from the products which are in the cart in an array skuInCart. Next I want to check if myVar is present in the skuInCart array. If so print myVar is found.
What happens is that you should expect that it prints only the matching results. However it actually prints all values present skuInCart (using keys filter) or completely blank without using keys filter.
What you are doing in theory should work, have a look a this fiddle example to show you a working demonstration:
https://twigfiddle.com/yvpbac
Basically:
<div id="certain_div">
This should not show up
</div>
{% set searchForSku = "890" %}
{% set productSkuArrayString = "1234,4567,890" %}
{% set productSkuArray = productSkuArrayString|split(',') %}
{% if searchForSku in productSkuArray %}
<style>
#certain_div {
display: none;
}
</style>
{% endif %}
<!-- New Trial -->
<div id="certain_div">
This should show up
</div>
{% set searchForSku = "891" %}
{% set productSkuArrayString = "1234,4567,890" %}
{% set productSkuArray = productSkuArrayString|split(',') %}
{% if searchForSku in productSkuArray %}
<style>
#certain_div {
display: none;
}
</style>
{% endif %}
Will result in:
<div id="certain_div">
This should not show up
</div>
<style>
#certain_div {
display: none;
}
</style>
<!-- New Trial -->
<div id="certain_div">
This should show up
</div>
You can use iterable to check if a variable is an array or a traversable object:
{% if items is iterable %}
{# stuff #}
{% endif %}
I have a problem with an array of arrays in Twig.
Here is the code I am struggling with :
{% set tabTmp = {0:{},1:{},2:{},3:{},4:{},5:{},6:{},7:{},8:{}} %}
{%for element in box.elements%}
{% set tab = tabTmp[element.category.id] %}
{% set elementId = element.id %}
{% set tab = tab | merge({elementId:element}) %}
{% endfor%}
{%for key, tmp in tabTmp %}
{% if tmp is iterable %}
{{ dump(tmp) }}
{% endif %}
{% endfor%}
box.elements and element exist, element.category.id and element.id are integer and element is the object I want to work with.
But I keep having Array(0) as a result of dump(tmp).
Any ideas ?
Everything looks fine, but if you want to merge a variable as key to an associative array you need to use ();
so try changing
{% set tab = tab | merge({elementId:element}) %}
To
{% set tab = tab | merge({(elementId):element}) %}
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 %}">