I need to show a value at the top of a page, which needs to be updated after I have run some Twig loops in the middle of the page.
Here's an example:
<div>Total Amount: {{ totalAmount }}</div>
{% for product in products %}
{% set totalAmount = totalAmount + product.amount %}
{% endfor %}
I could compute the value in the Symfony controller, but there are certain reasons why I would prefer doing this in the Twig template.
Is the above possible with Twig? I'm sure the Twig code is executed sequentially and I may have to find a different solution. But I'd like to see if anyone has any suggestions.
Thanks,
JB
Use blocks.
In your main template (layout):
<div>Total Amount: {% block totalAmount %}{% endblock %}</div>
In your child template:
{% for product in products %}
{% set totalAmount = totalAmount + product.amount %}
{% endfor %}
{% block totalAmount %}{{ totalAmount }}{% endblock %}
Related
Currently I have two arrays
{% set code = [AMS, EIN, RTM] %}
{% set city = [Amsterdam, Eindhoven, Rotterdam] %}
I would like to check if the value of {{airport}} exists in the first array and if it is code[0] I would like to change {{airport}} into the value of city[0]. Is this possible with Twig?
You can loop over the code array:
{% for c in code %}
{# ... #}
{% endfor %}
Documentation: https://twig.symfony.com/doc/2.x/tags/for.html
Then if the item does match:
{# ... #}
{% if airport == c %}
{# ... #}
{% endif %}
{# ... #}
Documentation: https://twig.symfony.com/doc/2.x/tags/if.html
Replace the variable airport, at the same loop index:
{# ... #}
{% set airport = city[loop.index0] %}
{# ... #}
Documentation: https://twig.symfony.com/doc/2.x/tags/for.html#the-loop-variable
So, in full:
{% for c in code %}
{% if airport == c %}
{% set airport = city[loop. index0] %}
{% endif %}
{% endfor %}
Running fiddle: https://twigfiddle.com/xflfas/2
Out of the scope note: your arrays would be better named cities and codes.
This way, when you loop over them, you end up with meaningful naming
{% set codes = ['AMS', 'EIN', 'RTM'] %}
{% for code in codes %}
{{ code }}
{% endfor %}
{# and #}
{% set cities = ['Amsterdam', 'Eindhoven', 'Rotterdam'] %}
{% for city in cities %}
{{ city }}
{% endfor %}
Use {% if value in array %} to search from the first array and Twig's merge function to replace the value in the second array. See this https://twig.symfony.com/doc/2.x/filters/merge.html
I am using Twig and Timber for a WordPress project. I have the following loop in my template that prints my custom post type titles into a HTML structure.
{% for company in companies %}
{% set dot = "<div class='company-dot'></div>" %}
{% set range = range(10, 20) %}
{{dot}}
{{random(range)}}
<div class="company">
<div class="company-dot dot-active"></div>
<p class="dot-caption">{{ company.title }}</p>
</div>
{% endfor %}
I would like to print my {{dot}} variable x amount of times based upon the number that is generated by {{random(range)}}. How can I do this?
The simplest solution would be to iterate random(range) times with a for loop:
{% for i in 0..random(range(10, 20)) %}
{{ dot }}
{% endfor %}
I don't really know Twig but my guess is that you could to the following:
{% for i in random(range) %}
{{dot}}
{% endfor %}
You already know how to use range, just use it again :
{% set dots_count = random(range) %}
{% for dot_index in range(1,dots_count) %}
{{dot}}
{% endfor %}
{{dots_count}}
Here is a fiddle : https://twigfiddle.com/ko595z
I am new to Twig and looking for a solution for the following (which would be very easy in PHP, however, our templates are setup in Twig)
What I'm trying to do
Edit an array value (using its index) in Twig so that it can be output after a loop.
What is happening
The array value (retrieved using its index) does not change when I try to edit the array value by index. Instead, it may append the value to the array
My code
...
{% set amount = [0,0,0] %}
{% for invoice in invoices %}
<tr>
<td>{% if invoice.age <= 10 %}{% set amount ?????? %}{% endif %}</td>
<td>{% if invoice.age > 10 and invoice.age <= 20 %}{% set amount ?????? %}{% endif %}</td>
<td>{% if invoice.age > 20 %}{% set amount ?????? %}{% endif %}</td>
</tr>
{% endfor %}
...
{{ amount[0] }}
What I've tried
I have tried the following to change the value of age[0] to no avail.
{% set amount = amount|merge({0: 'test'}) %}
{% set amount = amount|merge({0: 'test'})|keys %}
{% set amount = amount|merge({(0), 'test'}) %}
{% set amount = amount|merge({(0), 'test'})|keys %}
... and many more.
Intended outcome
I want to be able to output {{ age[0] }} at the end to display the amount total of all invoices aged 10 or less. Similarly, I would also like to output age[1] and age[2] to display amount total for all invoices aged between 10 and 20 days, and over 20 days, respectively.
In twig, always keep everything simple, without hard logic.
In your case, just create 3 variables.
{% set amount_under_10, amount_between_10_and_20, amount_over_20 = 0,0,0 %}
{% for invoice in invoices %}
<tr>
<td>{% if invoice.age <= 10 %}{% set amount_under_10 = amount_under_10 + 1 %}{% endif %}{{ invoice.age }}</td>
<td>{% if invoice.age > 10 and invoice.age <= 20 %}{% set amount_between_10_and_20 = amount_between_10_and_20 + 1 %}{% endif %}{{ invoice.age }}</td>
<td>{% if invoice.age > 20 %}{% set amount_over_20 = amount_over_20 + 1 %}{% endif %}{{ invoice.age }}</td>
</tr>
{% endfor %}
{{ amount_under_10 }}
{{ amount_between_10_and_20 }}
{{ amount_over_20 }}
See fiddle
If you need to be more generic (arbitrary number of ranges for example) don't do it in Twig. Twig is made for rendering information, no more.
See my answer here for a different approach.
I think I understand the idea behind keeping logic out of templates, but in my case I have SQL queries written by the administrator that are executed and a generic template outputs the results.
It makes more sense to calculate totals in the template.
We are making a website with a search form. In that form users can search with text and checkboxes. With the checkboxes users can search only in the related categories.
We need to accomplish this with Craft CMS and Twig.
We tried the following method, but that didnt worked.
{% set query = craft.request.getParam('search-results') %}
{% set nietBijdragePlichtig = craft.request.getParam('plg-Nee') %}
{% if nietBijdragePlichtig == 'on' %}
{% for entry in craft.entries.section('producten').limit(null).order(asc).search('query, nietBijdragePlichtig').find() %}
<div id=”test”>test</div>
{% endfor %}
{% endif %}
and we tried:
{% set query = craft.request.getParam('search-results') %}
{% set nietBijdragePlichtig = craft.request.getParam('plg-Nee') %}
{% set alle = query ~ ' ' ~ nietBijdragePlichtig %}
{% if nietBijdragePlichtig == 'on' %}
{% for entry in craft.entries.section(‘producten’).limit(null).order(asc).search(alle).find() %}
<div id=”test”>test</div>
{% endfor %}
{% endif %}
We also tried to use multiple .search()
We tried both codes with different syntaxes.
How can we accomplish this?
Really thanks!
I've made a recursive function in TWIG using a macro. This macro is supposed to count how many times it can find description in a nested array and return this.
Can anbody help me in solving what's going wrong. The fiddle can be found at:
https://twigfiddle.com/5uskoi
The result as you can see there is 4 while it should be 6.
Thanks for your time!
Regards,
Jasper
the TWIG code:
{% macro countArray(item) %}
{% import _self as self %}
{% set total = 1 %}
{% for yesItem in item.yes.items %}
{% set total = total + self.countArray(yesItem) %}
{% endfor %}
{% for noItem in item.no.items %}
{% set total = + total + self.countArray(noItem) %}
{% endfor %}
{{ total }}
{% endmacro %}
{% from _self import countArray %}
{% for item in data.items %}
{{ countArray(item) }}
{% endfor %}
with this data:
data:
items:
- description: '1'
yes:
items:
- description: '2'
- description: '3'
no:
items:
- description: '4'
yes:
items:
- description: '5'
- description: '6'
Found the solution to this problem. I have added |trim after the macro call. This trims all the whitespace and other stuff that got returned with the number.
This caused the problem of adding them together.
The twigfiddle has been updated with this settings for further reference!
Regards,
Jasper