For loop in twig using variables - twig

im trying to go through a loop multiple times and I want to use my variable to determine how many times the loop will be executed. But I cannot get it to work.
Im fairly new to Twig.
{% for item in items %}
{% for i in 1..item.content %}
<div>{{ item.content }}</div>
{% endfor %}
{% endfor %}
EDIT:
No clue what Im doing wrong. When I print item.content like this {{ item.content }} it outputs 5. But when I go trough the loop like in this example, I only get the result once

Related

How to render HTML to a variable

I need to render a list of HTML elements with content and put it into a variable. How can I do this efficient in twig?
e.g. I need to render the post tracking URLs from an order which can have several shippings / parcels.
{% for delivery in order.deliveries %}
{% for trackingCode in delivery.getTrackingCodes() %}
{{ trackingCode }}<br/>
{% endfor %}
{% endfor %}
Instead of printing this directly into the output I like first to put this rendered output into a variable like
{% set output = ... %}
...
{{ output }}
How can I do this in twig?
Just the concatenate the html to the output variable. Keep in mind you'll need to define to the variable outside the for-loop in order to use it outside the loop.
{% set foo = '' %}
{% for i in 1..10 %}
{% set foo = foo ~ ''~i~'' %}
{% endfor %}
{{ foo|raw }}
demo
After long search I found a better more efficient way
you can use {% set var %} with {% endset %} as a whole output block. Means the whole output will be set to the variable. This makes the life much easier and readable.
e.g.
{% set trackingText %}
{% for delivery in order.deliveries %}
{% for trackingCode in delivery.getTrackingCodes() %}
{{ trackingCode }}<br/>
{% endfor %}
{% endfor %}
{% endset %}
...
{% if trackingText|trim is not empty %}
You can track the delivery by using the following URL:<br/>
{{ trackingText }}
<br/>
{% endif %}

A For Loop in Jinja can't be used again or how to move First

When reusing the same SQLAlchemy Result to iterate it only works the first time.
See the below how I get all the qual.workforce but none of the displayname, busunit or certcount's:
<ul class="empltype">
{% for qual in allquals %}
<li>{{qual.workforce}}</li>
{% endfor %}
</ul>
<ul class="names">
{% for qual in allquals %}
<li>{{qual.displayname}}</li>
{% endfor %}
</ul>
<ul class="busunit">
{% for qual in allquals %}
<li>{{qual.busunit}}</li>
{% endfor %}
</ul>
<ul class="certcount">
{% for qual in allquals %}
<li>{{qual.certcount}}</li>
{% endfor %}
I would like to MoveFirst before the 3 loops for displaynames, busunit and certcount so they all work.
I don't want have 4 copies of the same variable (allquals1,2,3) even though I know that will work. I'm guessing the jinja render engine only iterates through objects once, is there a way to tell it to iterate over the same result set each time its used in a loop?
it happens just because the result is a generator, and it's values can be accessed only once. you have to do allquals = list(query_result) to iterate multiple times over it

TWIG / GravCMS: Use loop-variable of for-loop inside modular template

Here is my current code:
{% for module in page.collection() %}
{% set index = loop.index %}
{{ module.content|raw }}
{% endfor %}
I'd like to access index inside the module.html.twig, or even better, the entire loop variable.
How do I do that?
I found it myself:
{% for module in page.collection() if not module.header.visible is same as(false) %}
{% include module.template ~ '.html.twig' with {'page':module, 'loop':loop} %}
{% endfor %}
This loop willautomatically grab the template which is linked to the modular page and pass the required variables down. Also, the loop will only include modular subpages which are not hidden. Great, isn't it?

Check for paginate object in jinja2

I have a page which receives a results objects and is supposed to iterate over it. results can be a paginate object, in which case the iteration would be
{% for data in results.items %}
or it can be a list in which case we would iterate as
{% for data in results %}
I am now trying to distinguish between the two cases with
{% if results.items %}
{% for data in results.items %}
// do something with data
{% endfor %}
{% else %}
{% for data in results %}
// do something with data
{% endfor %}
{% endif %}
however, in my case it can happen that results.items == 0, which would mean that the if statement is false. Therefore I need to have a way to check whether results.items exists, independent of the value it has. Does anybody know how to do this?
it was easier than I thought...
{% if not results or (results.items is defined and not results.items) %}

How to filter image list with twig in grav

I am inserting a list of sponsor images in a sidebar in grav and want to show only images starting with sponsor_.
At the moment, my code adds any image in the page folder.
base.html.twig:
<div class="sidebar-right-content">
<!-- insert R sidebar images here -->
<div class="sponsor-image">
<h3>Sponsors</h3>
{% for image in page.media.images %}
<br>{{ image.html }}
{% endfor %}
</div>
I have tried restricting the images returned by using the expression below, but no images are returned:
{% for image in page.media.images if image matches '/^sponsor.*$/' %}
Is there a way to use a filter in this context?
try: {% image in page.media.images |contains('sponsor') %}
After some testing of a few options, I found a somewhat inelegant way to solve this problem.
The main thing to undertand is that page.media.images returns an array, so we can't filter this as a string.
So I just nested a match statement. I wonder if there's a one-liner solution.
{% for image in page.media.images %}
{% if image.html matches '/.*sponsor.*$/' %}
<br>{{ image.html }}
{% endif %}
{% endfor %}

Resources