Jinja conditional concatenation for html attribute - logic

I have the below jinja code to conditionally concatenate strings depending on two variables. Whilst it (probably) works it looks unwieldy, but I'd have thought this was a common thing to do when rendering.
{% if item.route %}
{% if item.route_follow and item.route_external %} {% set route_rel = 'external' %}
{% elif not item.route_follow and not item.route_external %} {% set route_rel = 'nofollow' %}
{% elif not item.route_follow and item.route_external %} {% set route_rel = 'nofollow external' %}
{% else %} {% set route_rel = '' %}
{% endif %}
{% endif %}
Is there a better way, maybe a one-liner?

When I got to the end of this I realised the answer:
{% if item.route %}
{% set route_rel = ['' if item.route_follow else 'nofollow', 'external' if item.route_external else '']|reject('==','')|join(' ') %}
{% endif %}
Sometimes, you just have to look at it again...

Related

How to show name specific tag in shopify

I want to display the value of a specific product tag in my shopify store.
The product tag always starts with Color_ followed by the color Color_Green
I want to display only green. (I can use split or slice for that part)
But I can't figure out to only display the tag that starts with Color_ because I have multiple tags added to my products.
This is my code for now:
{%- for tag in product.tags -%} {%- assign tag_prefix = tag %} {%- if tag_prefix == "Color_" -%} {%- endif -%} {%- endfor -%}
Try this snippet
{% for tag in product.tags %}
{% assign tag_prefix = tag %}
{% if tag_prefix contains "Color_" %}
{% assign tagValue = tag_prefix | replace: "Color_", "" %}
{{ tagValue }}
{% endif %}
{% endfor %}

ansible jinja2 - how to use "loop range" output in other "for statement"

I want to use the n values in the next for statement and I expect output as router_0, router_1. But any optisons like router_[n], router_{{ n }}, router_(n) etc didnt work. How can we do this?
{% for n in range(0, 2) %}
{% for rtr in web.router_[n] %}
{% if rtr.interface.type == 'lacp' %}
interface Port-Channel{{ rtr.interface.id }}
.
{% endif %}
{% endfor %}
{% endfor %}
In vars.yaml, there are variables for paired routers, router_0 and router_1. I want to generate the config template for both routers at the same time.
Thanks,
Concatenate the name of the attribute
{% for rtr in web['router_' ~ n] %}

How do I show a tag to represent multiple products? Shopify Liquid

Hello and thanks for reading my post!
I have a collection with multiple products. On a custom collection template, I want to show the tags only for those that contain multiple products (or when more than 1 product in that collection have the same tag)
I assume it would go something like:
{% for tag in collection.all_tags %}
{% if tag.product.size >= 1 %}
has more than 1 product.
{% endif %}
{% endfor %}
I've answered similar questions here and here.
You want something like this:
{% for tag in collection.all_tags %}
{% assign products_count = 0 %}
{% for product in collection.products %}
{% if product.tags contains tag %}
{% assign products_count = products_count | plus: 1 %}
{% endif %}
{% endfor %}
{% if products_count > 1 %}
{{ tag }}
{% endif %}
{% endfor %}

Shopify: how to get value of forloop.index outside of the loop?

When I attempt to assign the forloop index (or anything else) to a variable in a for-loop and then use it outside (after) the loop, the assigned value is lost. The code below is one of about 20 different approaches I have tried. None of them have worked. I just need to know if x contains y (so the variable can either be boolean or an integer or anything).
{% assign has_y = 0 %}
{% for x in collection %}
{% if x contains y %}
<span style="display: none">{{ has_y | plus: 1 }}</span>
{% endif %}
{% endfor %}
{% if has_y < 1 %}
THIS DOESN'T WORK AS EXPECTED
{% endif %}
I'm confused about Shopify's scoping rules...
The problem is you are outputting {{ has_y | plus: 1 }}, but not assigning anything to has_y inside the for loop.
Try this:
{% assign has_y = 0 %}
{% for x in collections %}
{% if x contains y %}
{% assign has_y = has_y | plus: 1 %}
<span style="display: none">{{ has_y }}</span>
{% endif %}
{% endfor %}
{% if has_y < 1 %}
...
{% endif %}
Or, if you want to use boolean values instead:
{% assign has_y = false %}
{% for x in collections %}
{% if x contains y %}
{% assign has_y = true %}
<span style="display: none">{{ has_y }}</span>
{% endif %}
{% endfor %}
{% if has_y == false %}
...
{% endif %}
Also, you may want to check your for loop {% for x in collection %}. collection is an object. Maybe you meant to iterate over collection.products or collections instead?

select previous item in twig for loop

I use twig and have some data in array. I use for loop to access all data like this:
{% for item in data %}
Value : {{ item }}
{% endfor %}
Is it possible to access previous item in loop? For example: when I'm on n item, I want to have access to n-1 item.
There's no built-in way to do that, but here's a workaround:
{% set previous = false %}
{% for item in data %}
Value : {{ item }}
{% if previous %}
{# use it #}
{% endif %}
{% set previous = item %}
{% endfor %}
The if is neccessary for the first iteration.
In addition to #Maerlyn 's example, here is code to provide for next_item (the one after current one)
{# this template assumes that you use 'items' array
and each element is called 'item' and you will get
'previous_item' and 'next_item' variables, which may be NULL if not availble #}
{% set previous_item = null %}
{%if items|length > 1 %}
{% set next_item = items[1] %}
{%else%}
{% set next_item = null %}
{%endif%}
{%for item in items %}
Item: {{ item }}
{% if previous_item is not null %}
Use previous item here: {{ previous_item }}
{%endif%}
{%if next_item is not null %}
Use next item here: {{ next_item }}
{%endif%}
{# ------ code to udpate next_item and previous_item elements #}
{%set previous_item = item %}
{%if loop.revindex <= 2 %}
{% set next_item = null %}
{%else%}
{% set next_item = items[loop.index0+2] %}
{%endif%}
{%endfor%}
My solution:
{% for item in items %}
<p>item itself: {{ item }}</p>
{% if loop.length > 1 %}
{% if loop.first == false %}
{% set previous_item = items[loop.index0 - 1] %}
<p>previous item: {{ previous_item }}</p>
{% endif %}
{% if loop.last == false %}
{% set next_item = items[loop.index0 + 1] %}
<p>next item: {{ next_item }}</p>
{% endif %}
{% else %}
<p>There is only one item.</p>
{% endif %}
{% endfor %}
I had to make endless image gallery where before first item goes last one and after last item goes first one. It could be done this way:
{% for item in items %}
<p>item itself: {{ item }}</p>
{% if loop.length > 1 %}
{% if loop.first %}
{% set previous_item = items[loop.length - 1] %}
{% else %}
{% set previous_item = items[loop.index0 - 1] %}
{% endif %}
{% if loop.last %}
{% set next_item = items[0] %}
{% else %}
{% set next_item = items[loop.index0 + 1] %}
{% endif %}
<p>previous item: {{ previous_item }}</p>
<p>next item: {{ next_item }}</p>
{% else %}
<p>There is only one item.</p>
{% endif %}
{% endfor %}

Resources