Symfony2 displaying dynamically values from array to twig - php

I have a function in which I count the final price of each product and I save it in an array. Now when I want do display the values I am stuck at how to display all of them dynamicaly.
This is the function:
public function getTotal($items)
{
$total = array();
foreach($items as $key=>$item){
$total[$key] = $item->getPrice() - $item->getDiscount() + $item->getValue();
}
return $total;
}
All of the methods getValue, getDiscount and etc are working.
This is how I try o display:
{{ getTotal(product)[key]}}
The problem is that when I write for example {{ getTotal(product)[0]}} or {{ getTotal(product)[1]}} and etc i get the correct value, but only of 1 product. I need to get the values from all of them.
If i do {{ getTotal(product)[key]}} im getting a strange error:
Key "12" for array with keys "0, 1" does not exist in MpShopBundle:Frontend:product_summary.html.twig at line 89
I have no idea why the key is equal to 12? Maybe I have to write something different?
UPDATE
Thank you for the answers, I didnt even think about looping with twig, but I am finally getting some values. However, I dont know why but the twig loop assigns both values for each product.
This is how it should be:
Product1 : 0(key):145(value)
Product2 : 1:415
But this is how it is:
Product1 : 0:145 1:415
Product2 : 0:145 1:415
This is the twig:
{% if product is defined %}
{% for key, item in cart %}
{% for item in product %}
<tr>
<td> <img width="60" src="{{ asset('bundles/mpFrontend/assets/products/4.jpg') }}" alt=""/></td>
<td>{{ item.model }}</td>
<td>
<div class="input-append"><input class="span1" style="max-width:34px" placeholder="1" id="appendedInputButtons" size="16" type="text">
<button class="btn" type="button"><i class="icon-minus"></i></button>
<button class="btn" type="button"><i class="icon-plus"></i></button>
<button class="btn btn-danger" type="button"><a href="{{ path('cart_remove', {'id': key}) }}"><i class="icon-remove icon-white"></i></button>
</div>
</td>
<td>{{ item.price }}</td>
<td>{{ item.discount }}</td>
<td>{{ item.value }}</td>
{% if getTotal(product) is iterable %}
{% for key, sum in getTotal(product) %}
<td>{{ key }}:{{ sum }}</td>
{% endfor %}
{% endif %}
</tr>
{% endfor %}

Use twig for loop:
{% for total in getTotal(product) %}
{{ total }}
{% endfor %}

You can use the twig for loop.
Example:
{% if getTotal(product) is iterable %}
{% for key, sum in getTotal(product) %}
{{ key }}:{{ sum }}
{% else %}
empty array
{% endfor %}
{% endif %}

You shouldn't use a loop, and move your function from an external to a method of the product class.
Instead of loop:
<td>{{ product.total }}</td>
New function:
class Product {
...
public function getTotal()
{
return $this->getPrice() - $this->getDiscount() + $this->getValue();
}
}

Related

translate tabledata in twig

I fill my table with data in this way
<tbody>
{% for post in posts %}
<tr>
<td>{{ post.title }}</td>
<td>{{ post.status }}</td>
</tr>
{% endfor %}
</tbody>
I need translate values from status, but it does not work. post.status has only 2 values in database PO_DRAFT and PO_ACCEPT and I need it translate. Is it possible?
I tried in this way but it is wrong
<td>{% trans %}{{ post.status }}{% endtrans %}</td>
Twig's i18n documentation mentions a trans filter, so maybe this would work?
{{ post.status | trans }}

How use rendered variables in a foreach Symfony 2 ~ twig

its not the first time I met this issue and I cannot fix it!
Actually, I'm rendering a template with a controller who give to the rendered page many variables. One of them, called $categories, in it, There are many of Category objectes so, one of them its a Collection what references to another Category.
The point is, I'm try to do this code, but obviusly I get an error because im trying to print as a String a Collection
{% for category in categories %}
<tr>
<td>{{ category.name }}</td>
<td>{{ category.description }}</td>
<td>{{ category.isPublic }}</td>
<td>{{ category.parentCategory }}</td>
<td>{{ category.childrens }}</td>
<td>
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
<i class="fa fa-times" aria-hidden="true"></i>
</td>
</tr>
{% endfor %}
So, I decided to try something like:
{% for category in categories %}
<tr>
<td>{{ category.name }}</td>
<td>{{ category.description }}</td>
<td>{{ category.isPublic }}</td>
<td>{{ category.parentCategory }}</td>
<td>
{% for children in {{ category.childrens }} %}
children.name
{% endfor %}
</td>
<td>
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
<i class="fa fa-times" aria-hidden="true"></i>
</td>
</tr>
PROBLEM:
I don't know how use a rendered variable in a foreach, im gettin this error:
A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "punctuation" of value "{" in AppBundle:admin:category/listCategory.html.twig at line 55.
{{ }} or {% %} or {# #} are Twig's open and close tags. Similair to <?php ?> in PHP code. Once you use an open tag, the text is parsed by Twig until the close tag is found (this is also how things are done in PHP, the only difference is that Twig has a different tag to echo stuff).
Once open, you don't have to reopen it again. You don't want to dump category.childrens, you want to use it in the for loop. So instead of doing: {% for children in {{ category.childrens }} %}, use {% for children in category.childrens %}.
(you can compare this to PHP, doing
<?php foreach (<?php echo $category->childrens ?> as $children) { ?>
doesn't make much sense).
The error probably comes from this line:
{% for children in {{ category.childrens }} %}
This is not a valid syntax, the {{ }} can't be used inside another Twig tag.
The following code should work:
{% for children in category.childrens %}
To be honest I have 0 experience with the twig templating langauge, so I may be wrong here, but my experience with other languages tells me the following code:
{% for children in {{ category.childrens }} %}
children.name
{% endfor %}
Should probably look like this:
{% for children in category.childrens %}
{{ children.name }}
{% endfor %}

Twig if/else not working

I'm not sure why my code isn't executing. I know that it should be working this way but all that happens now is that it doesn't do the else portion.
In debugging I know descriptions is not null and descriptions show for those that have it.
{% if descriptions is not null %}
{{ dump(descriptions) }}
{% for description in descriptions %}
<td>{{ description.productDesciption }}</td>
{% endfor %}
{% else %}
<td>
Create a Description for this Product
</td>
{% endif %}
You can simplify using the The else Clause of the for statement:
{% for description in descriptions %}
<td>
{{ description.productDesciption }}
</td>
{% else %}
<td>
Create a Description for this Product
</td>
{% endfor %}
Hope this help
You can use if into for loop.
{% for description in descriptions if descriptions is not null %}
<td>
{{ description.productDesciption }}
</td>
{% else %}
<td>
Create a Description for this Product
</td>
{% endfor %}

Twig doesn't approximate number

I have a strange situation. My code is :
{% set total_amount=0 %}
{% for result in a_result %}
<tr>
<td>{% set total_amount=total_amount+("%.2f"|format(result.tva*result.prix_ht)) %}
{{ "%.2f"|format(result.tva*result.prix_ht) }}
</td>
/tr>
{% endfor %}
<tr>
<td colspan="5">Total</td>
<td>{{ total_amount }}</td>
</tr>
As result I have :
15.98, 25.49, 25.49
And Total = 65 but total should be equal with 65.96. I don't understand where is the problem. Can you help me please ?
I suggest you to use the round and number_format filter as follow:
{% set total_amount=0 %}
{% for result in a_result %}
{% set value = (result.tva* result.prix_ht)|round(2) %}
{% set total_amount=total_amount+value %}
<tr>
<td>
{{ value|number_format(2, '.', ',') }}
</td>
/tr>
{% endfor %}
<tr>
<td colspan="5">Total</td>
<td>{{ total_amount|number_format(2, '.', ',') }}</td>
</tr>
A running example with sample data in this twigfiddle files
Hope this help

Twig: set a variable inside a loop, use it outside that loop

I'm trying to define driverid, using set, as a var in for driver in assigned.driver cycle for use later. See below what I'm doing:
{% for key, assigned in pgn %}
<tr id="device-{{ assigned.id }}">
<td>{{ assigned.imei }}</td>
<td>{{ assigned.description }}</td>
<td>
{% for driver in assigned.driver %}
{{ driver.driver.id }} {# check if driver.driver.id has values testing purposes - delete me #}
{% set driverid = driver.driver.id %}
{% if driver.driver.name != "" %}
{% if driver.driver.name %}
{{ driver.driver.name }}
{% else %}
-
{% endif %}
{% endif %}
{% endfor %}
</td>
<td>
<button class="btn btn-xs btn-default"
onclick="openAlert({{ assigned.id }}, {{ driverid }}, 'unlink')"
data-original-title="{{ "devices.actions.unlink"|trans }}"
title="{{ "devices.actions.unlink"|trans }}">
<i class="fa fa-times"></i>
</button>
<button class="btn btn-xs btn-default"
onclick="openAlert({{ assigned.id }}, null, 'delete')"
data-original-title="{{ "button.delete"|trans }}"
title="{{ "button.delete"|trans }}">
<i class="fa fa-times"></i>
</button>
</td>
</tr>
{% endfor %}
But I get this error:
Variable "driverid" does not exist in
/var/www/html/src/Device/DeviceBundle/Resources/views/List/listDevices.html.twig
at line 74
What's the right way to set that var to use later on openAlert() call? Or in others words how I get the driver.driver.id to pass it as a parameter to openAlert() function?
As they say here, this is not a bug, it's a feature: variables defined inside a loop are scoped to that loop.
But don't worry, you can define the var outside the loop and assign it inside, like this:
{% set driverid = '' %} {# <-- add this line: default empty value #}
{% for driver in assigned.driver %}
...
{% set driverid = driver.driver.id %}
this should be enough to make it work.
If assigned.driver is empty, then the for loop is never executed so the variable won't be defined. What you need to do is to initialize this variable outside of the loop: {% set driverid = null %}

Categories