How to check if condition in django template part - django-templates

I want add simple css class in the template first round of loop when for loop runs. {{forloop.counter}} shows count of for loops each time. so I want to do something like this {% if forloop.counter==1 %} show {% endif %}. but it shows error as below:
Could not parse the remainder: '==1' from 'forloop.counter==1'
How to do it? any solution?

You're forgetting about the spaces around the equal signs:
{% if forloop.counter == 1 %}

Related

Cycle inside render tag

I am looping through products and I need the cycle tag based on loop.
{% for product in collection.products %}
{% render 'product-grid-item', product: product %}
{% endfor %}
Inside the "product-grid-item", I have:
{% assign class_1 = 'small-6 medium-4' %}
{% assign class_2 = 'small-6 medium-3' %}
{% capture grid_item_width %}
{% cycle class_1, class_1, class_1, class_2, class_2, class_2, class_2 %}
{% endcapture %}
The cycle is not working, because it is not directly inside the "for loop". Any idea how to get this working?
I am aware of alternatives, I am just trying to make "cycle" work inside a render tag.
Render is a closed piece of code, it can't read what is happening outside of it.
So at the moment you not only don't have access to the cycle but you don't have access to the forloop object as well.
You are looking for how the include works but that is deprecated and you shouldn't use it.
So the short answer is you can't make it work, since the main logic of the render is to work this way.
The only way to make the render aware of something outside it is to pass a variable to it, so you need to make your cycle logic outside of it and pass the resulting variable inside of it.
What you are trying to do is possible as long as you rearrange your approach slightly. You will just need to do your math outside of the snippet and pass an appropriate value as a variable into the snippet.
{% assign class_array = 'class-1,class-1,class-1,class-2,class-2,class-2,class-2' | split: ',' %}
{% for product in collection.products %}
{% assign loop_position = forloop.index0 | modulo: class_array.size %}
{% render 'product-grid-item', product: product, class_name: class_array[loop_position] %}
{% endfor %}
How this works
Just like before, we make a comma-separated array of class names that we want to cycle through. (We cannot make an array directly, but we can turn a delimited string into an array pretty easily using the split filter) - but this time we assign that to a variable.
We then use the forloop index and the modulo operator to get a value between 0 and the last index position of our array list and use that number as the lookup value for our array. That value is passed into the rendered snippet so that product-grid-item can access it.
If we ever need to change our cycling class names, all we have to do is update the array with the new values. Even if the number of values changes in the future, the code will still work to cycle through all of the values provided.
Cheers!

Liquid : How do I combine two conditions?

Liquid novice here looking for some help. I have two collections and one product in each collection that have similar names:
(collection) Snack Bars > (product)Chocolate Chip
(collection) Protein Bars > (product)Mint Chocolate Chip
I am trying to hide/show content specific to those items (within the same page) based on the collection and product handle. I've tried the following, but this shows both items even though == should be specific, it's not and displays as it considers chocolate-chip and chocholate-chip-mint to be a match, but it's not:
{% if product.handle == "chocolate-chip" %} // do something {% endif %}
I've tried this, but no go:
{% if collection == "protein-bars" && product.handle == "mint-chocolate-chip" %} // do something {% endif %}
I've also tried this but it doesn't work:
{% if product.handle == "mint-chocolate-chip" | within: collections.protein-bars %} // do something {% endif %}
Ultimately, I just want to verify that if I'm on a product page, my logic checks:
That the product handle in the URL matches (exactly) mint-chocolate-chip.
That the item is a part of the collection : protein-bars (not snack bars)
https://www.blakesseedbased.com/collections/snack-bars/products/chocolate-chip
https://www.blakesseedbased.com/collections/protein-bars/products/mint-chocolate-chip
You can see on the Mint Chocolate Chip page the logic believes "chocolate-chip" is a product match, and is displaying the information for chocolate-chip on the mint-chocolate-chip page (in the white section under the product display).
Some things to keep in mind when writing your liquid statements:
Liquid is verbose - it uses the literal words and and or for comparisons. Example: {% if product.price > 1000 and product.price < 2000 %}
Conditionals cannot contain parentheses. Or at least, they can but they're ignored. Result: Best practice is to only use and or or in any single statement.
You cannot use filters inside of if (or unless) statements - you will want to use assign first to create a variable with all the filters applied first, then do your comparisons on that.
In addition to ==, >, < and !=, you can use contains inside your statements. If you're using contains on a string, you will match a substring; if you're using contains on an array, you will match an exact value in the array. (Note: you cannot use contains on an array of complex objects, like an array of variants)
Collections are objects, so it can never equal a string. You should test for a collection based on some property, such as collection.handle
The map filter is a handy way to reduce an array of complex objects into an array of simple fields
So something you could do:
{% assign product_collections = product.collections | map: 'handle' %}
{% if product_collections contains 'my-special-collection' and product.handle == 'my-special-handle' %}
<h2>Hi Mom!</h2>
{% endif %}

Jinja / Django for loop range not working

I'm building a django template to duplicate images based on an argument passed from the view; the template then uses Jinja2 in a for loop to duplicate the image.
BUT, I can only get this to work by passing a list I make in the view. If I try to use the jinja range, I get an error ("Could not parse the remainder: ...").
Reading this link, I swear I'm using the right syntax.
template
{% for i in range(variable) %}
<img src=...>
{% endfor %}
I checked the variable I was passing in; it's type int. Heck, I even tried to get rid of the variable (for testing) and tried using a hard-coded number:
{% for i in range(5) %}
<img src=...>
{% endfor %}
I get the following error:
Could not parse the remainder: '(5)' from 'range(5)'
If I pass to the template a list in the arguments dictionary (and use the list in place of the range statement), it works; the image is repeated however many times I want.
What am I missing? The docs on Jinja (for loop and range) and the previous link all tell me that this should work with range and a variable.
Soooo.... based on Franndy's comment that this isn't automatically supported by Django, and following their link, which leads to this link, I found how to write your own filter.
Inside views.py:
from django.template.defaulttags import register
#register.filter
def get_range(value):
return range(value)
Then, inside template:
{% for i in variable|get_range %}
<img src=...>
{% endfor %}

Incrementing variables in liquid without outputting them

I am doing a for loop in shopify, I need to increment a variable.
However, when I do
{% increment variable %}
besides incrementing it, it shows the output on the screen!
I can't believe it. Is there a way to avoid this?
Thank you
If you are using a different logic for incrementing the value than forloop.index, you can use the plus filter to increment the variable:
{% assign variable = 0 %}
{% for … %}
{% assign variable = variable | plus: 1 %}
{% endfor %}
I can also recommend that you have a look at the cheat sheet for Shopify.
This is by design, at it allows you to increment and display a variable at the same time. See the documentation.
assign only allows you to assign new variables (and not modify existing ones), so aside from creating a new tag, the easiest way is to use use capture to capture the output:
{% capture _ %}{% increment variable %}{% endcapture %}
That being said, perhaps it's time to re-consider why exactly you're doing this? Note that you already have forloop.index and forloop.index0 available for the loop index (once again, see the documentation).

Variable within liquid if statement when calling shopify settings

I thought this would be simple to solve but I am trying to put a variable within a liquid statement.
I have my variable {{ loop_index }} and I want it to be within this statement :
{% if settings.dropdown-[loop_index]-select %}
I tried putting [...] round it but that didn't work. Basically it should say settings.dropdown-1-select, settings.dropdown-2-select.
What am I doing wrong?
Create a string containing the variable name, then use the square bracket notation to access the setting with that name. For example:
{% capture var %}dropdown-{{ loop_index }}-select{% endcapture %}
{% if settings[var] %}