Breaking Nunjucks Loop - node.js

I've racked my brain in all directions but still no solution. Maybe someone has some advice?
I have the following block in an ExpressJS app using Nunjucks as the templating engine.
{%- for course in courses -%}
{%- for rcourse in report.courses -%}
{%- if rcourse.id == course.id -%}
<li {{ 'class="column-pre"' if loop.last else ''}}><span>Cool!</span></li>
{%- else -%}
<li></li>
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
My problem: I need to break the inner report.courses loop when the conditional proves truth-y. Basically, the moment that I print the non-empty <li> line, I need to jump to the next iteration of the courses loop.
I know that Nunjucks does't have a break for loops like Jinja2, Nunjucks' variables are scoped (so I can't set a sentinel-like variable that gets modified in the if/else statement), nor can I append to an array so that I can use array.length as a way to determine if I should print the <li></li> line.
Maybe someone has a clever solution?

I think the sentinel-like variable would not be affected by scoping:
{% for course in courses %}
{% set searchrcourse = true %}
{% for rcourse in report.courses %}
{% if searchrcourse %}
{% if rcourse.id == course.id %}
<li {{ 'class="column-pre"' if loop.last else ''}}><span>Cool!</span></li>
{% set searchrcourse = false %}
{% else %}
<li></li>
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}

Related

Shopware6 Social Shopping: Google Shopping Feed: Varianten template <g:size>

H
I added structured data values such as:
<g:color>, <g:material>.
{% for properties in product.properties %}
{% if properties.group.name == "Kolor" %}
<g:color>{{ properties.name }}</g:color>
{% endif %}
{% endfor %}
{% for properties in product.properties %}
{% if properties.group.name == "Skład" %}
<g:material>{{ properties.name }}</g:material>
{% endif %}
{% endfor %}
, but I don't know how I can add <g:size> from product variants?
First of all you have to enable "Export variants as discrete products" in the settings of your product comparison sales channel.
There are two separate association to properties:
product.properties for general properties, not necessarily variant specific
product.options which define the combination of properties for a specific variant.
You may want to iterate product.options instead.
0
I tried this:
{%- if product.variation -%}
{%- for variation in product.variation -%}
{%- if variation.group == 'Kolor' -%}
<g:color>{{ variation.option }}</g:color>
{%- endif -%}
{%- if variation.group == 'Wymiary' -%}
<g:size>{{ variation.option }}</g:size>
{%- endif -%}
{%- endfor -%}
{%- endif -%}
But it doesn't work
First of all you have to enable "Export variants as discrete products" in the settings of your product comparison sales channel.
There are two separate association to properties:
product.properties for general properties, not necessarily variant specific
product.options which define the combination of properties for a specific variant.
You may want to iterate product.options instead.

How to create array using Tera in Rust?

I am stuck in a simple problem but not able to figure it. I am not sure if this is the right place to ask the question on a package in Rust.
Most of the time, in the template, we will want to transform our data. For example, I wanted to concat n arrays in one line. I can use ~ operator only if I know the number of arrays.
Below is the requirement I am looking for,
{% macro generate_table(table) %}
{% for rows in 0..table.length %}
{{ table[table.col_header[0]][row] ~ " || " ~ [table.col_header[1]][row] }}
{% endfor %}
{% endmacro input %}
I want to do.
{% macro generate_table(table) %}
{% for rows in 0..table.rlength %}
{% for cols in 0..table.clength %}
{{ arr.insert(table[table.col_header[cols]][row]) }}
{% endfor %}
{{ arr | join(sep=" || ") }}
{% endfor %}
{% endmacro input %}
I figured it out. Using concat(with="")
{% macro generate_table(table) -%}
{% for row in [0,1,2] -%}
{% set_global row_val = [] -%}
{% for cols in [0,1,2] -%}
{% set_global row_val = row_val | concat(with= table.col_values[table.col_header[cols]][row]) -%}
{% endfor -%}
{{ row_val | join(sep=" ") }}
{% endfor -%}
{% endmacro generate_table -%}

How to chop inside a for-loop in Twig

This is a refactoring question. The code works as is, I'm just not happy with it in an aesthetical sense.
I would like to know if the conditional inside the loop can be written in a shorter, more readable way or maybe can be stripped away?
{% set i = 0 %}
{% for element in list %}
{% if loop.first %}<div class="row">{% endif %} {# open first row #}
{% if i > 2 %} {# new row every 3 elements #}
{% set i = 0 %}
</div>
<div class="row">
<img src="{{ element.url }}">
{% else %}
{% set i = i+1 %}
<img src="{{ element.url }}">
{% endif %}
{% if loop.last %}</div>{% endif %}
{% endfor %}
As user DarkBee said, have a look into batch.
{% for element in list|batch(3) %}
.....
.....
{% endfor %}
Just to have an example on this page.
Batch-Docs
Regards

A solution for grouping items in loop with Timber and Twig

Often i need to do some tricky layout on dynamic elements like galleries.
Here's one example:
<ul>
<li class="slide">
<img src="img_01.jpg">
<img src="img_02.jpg">
</li>
<li class="slide">
<img src="img_03.jpg">
<img src="img_04.jpg">
</li>
<li class="slide">
<img src="img_05.jpg">
<img src="img_06.jpg">
</li>
</ul>
I've managed to do it with the following snippet. But i wanted some suggestions if possible about how to make it more flexible or more simple, like grouping by any number. Maybe using cycle() or any other method. I was getting strange results using the slice() or array[1:2] notation.
<ul>
{% for image in gallery %}
{% set current = loop.index %}
{% set next = current + 1 %}
{% if current is odd %}
<li class="slide">
{% for image in gallery %}
{% if loop.index in [current,next] %}
{% set th = TimberImage(image) %}
<img src="{{th.src}}">
{% endif %}
{% endfor %}
</li>
{% endif %}
{% endfor %}
</ul>
Any suggestions are welcomed.
Timber becomes very handy for quick in and out fixes with Timber::compile or custom themes with full routing. The purpose of the question is to create some snippet that can be reused.
Kudos to creators.
https://github.com/timber/timber
You can approach with the rest of the division with the following code (Here a working solutions):
{# number of element for every section #}
{% set section = 2%}
<ul>
{% for image in gallery %}
{% if loop.index % section == 1 %}
<li class="slide">
{% endif %}
{% set th = TimberImage(image) %}
<img src="{{th.src}}">
{% if loop.index % section == 0 or loop.last %}
</li>
{% endif %}
{% endfor %}
</ul>
You can easily reuse this code making a Twig macro using as parameter the gallery and the number of element for section (highlighted with the variable section
Here's the final result taking the suggestion of #Matteo for a macro:
https://gist.github.com/lithiumlab/5ee0454b0a77b1cc26fc0ce8ba52fd80
views/single.twig:
{% import 'utils.twig' as utils %}
{{utils.group_collection(gallery,3)}}
views/utils.twig:
{% macro group_collection(collection, groupby) %}
{% set section = groupby|default(2) %}
<ul>
{% for element in collection %}
{% if loop.index % section == 1 %}
<li class="group">
{% endif %}
{% set th = TimberImage(element) %}
<img src="{{th.src}}">
{% if loop.index % section == 0 or loop.last %}
</li>
{% endif %}
{% endfor %}
</ul>
{% endmacro %}

for loop counter with Twig or Swig

Anyone know of a clean way to do this in Twig/Swig:
{% for(i = 0; i < 100; i++) %}
blah....
{% endfor %}
If you have a number, then you can just convert this to an array and then use Swig's standard for tag. This is simplest if you always want to 'start' the loop from 0 though.
For example:
{% set productCount = 6 %}
{% set productCountAsArray = Array(productCount) %}
{# This will run productCount times #}
{% for x, y in productCountAsArray %}
This is for number: {{ x }}
{% endfor %}
The swig docs have since (ivoba's answer) been updated and now contain special loop variables, which include loop.index:
{% for x in y %}
{% if loop.first %}<ul>{% endif %}
<li>{{ loop.index }} - {{ loop.key }}: {{ x }}</li>
{% if loop.last %}</ul>{% endif %}
{% endfor %}
http://paularmstrong.github.io/swig/docs/#tags-for
For twig its:
{% for i in 0..100 %}
* {{ i }}
{% endfor %}
From http://twig.sensiolabs.org/doc/tags/for.html
For swig the docs dont mention it yet:
https://github.com/paularmstrong/swig/blob/master/docs/tags.md#for
i cant really tell but it might be not supported in swig since its django inspired and django also seems to lack this feature nativly: https://code.djangoproject.com/ticket/5172
so i would like to pass the swig part to the next one.

Resources