Django is there an 'empty' with 'for' loop having a 'if' condition? - django-templates

I have this:
{% for prop in props %}
{% if prop.status == 'SOLD' %}
{{ name }}
{% endif %}
{% empty %}
<li>No closed deals.</li>
{% endfor %}
and of course it doesn't do what I want, as far as an empty if loop.
Aside from just filtering the statuses into lists from the view, is there an empty for this kind of loop? I tried setting a true/false using a {% with sold=True %}, but it doesn't work that way.

You can do something like below, which would mean if a value is empty, False, or None it will evaluate to true:
{% if not prop.status %}
do something
{% endif %}
OR
use an else statement, which would catch all values that are not 'SOLD'
{% if prop.status == 'SOLD' %}
do stuff
{% else %}
do something else
{% endif %}

Related

shopoify liquid tags if else unless

I need to customize the shipping confirmation email. I want to use a tag to determine which of two text sections are included in the email. The problem is there is usually an array of tags. I can get section "A" like this...
{% for tag in tags %}
{% if tag == 'a' %}
A
{% endif %}
{% endfor %}
There is only a single 'a' tag in the array so I only get the "A" text once.
But I can't figure out how to get the "B" text to appear just one time.
If I do this, it appears for every tag that does not == 'a'...
{% for tag in tags %}
{% unless tag contains 'a' %}
B
{% endunless %}
{% endfor %}
Is there a way to get one instance of "B"?
You could repeat the same logic you did for A:
{% for tag in tags %}
{% if tag == 'a' %}
A
{% endif %}
{% if tag == 'b' %}
B
{% endif %}
{% endfor %}
Alternatively you could do a switch/case statement, I'd prefer this approach because it's easy to read, and if sometime in the future you would like to add another condition (tag), it would be easy and the code would still keep its elegance.
{% for tag in tags %}
{% case tag %}
{% when 'a' %}
A
{% when 'b' %}
B
{% when 'c' %}
C
{% endcase %}
{% endfor %}
If you have many tags it can become tricky, but if it's just two tags this is the general idea.
{% assign a_not_found = true %}
{% for tag in tags %}
{% if tag == 'a' %}
...
{% assign a_not_found = false %}
{% endif %}
{% endfor %}
{% if a_not_found %}
{... show b... }
{% endif %}
Otherwise
{% if tags contains 'a' %}
{...show a...%}
{% else %}
{...show b...%}
{% endif %}

Getting collection's linklist to then get the handle to compare to main-menu in shopify

Say this is my navigational structure in shopify:
Shoes
Flats
Sandals
Bags
Currently I've gotten a fairly simple navigational component working, where if you're on a page (let's say shoes) the navigation on the page will highlight, because it matches the menu's handle with the page handle. Good so far:
{% for link in linklists.main-menu.links %}
<span><a
{% if collection.handle == link.handle %}
class="current"
{% endif %}
href="{{ link.url }}"> {{ link.title }}</a></span>
{% endfor %}
Now the question is, how do I check the sub-collection (Flats) and match it with it's parent collection to then do the same thing?
You need to adjust this condition
{% if collection.handle == link.handle %}
class="current"
{% endif %}
so that it check for the internal links as well. Add this snippet before this condition
{% assign sub_link = false %}
{% assign inside_links_handle = link.handle %}
{% for inside_link in linklists[inside_links_handle].links %}
{% if collection.handle == inside_link.handle %}
{% assign sub_link = true %}
{% break %}
{% endif %}
{% endfor %}
And change the condition to this {% if collection.handle == link.handle or sub_link == true %} class='current' {% endif %}
Here you are looking inside the linklist which is inside another linklist (nested). More nesting levels, just iterate the code to consider inside levels. This should work.

How to hide products in Shopify search results based on a vendor name

I'm in a situation where hiding a certain vendors products in the control panel isn't an options due to an outside POS. For a test in search.liquid, I used search.terms like below. This code works but not everyone will type thevendor exactly the same way and will see the products if they don't type thevendor.
{% for item in search.results %}
{% if search.terms == 'thevendor' %}
{% else %}
{% include 'search-result' %}
{% endif %}
{% endfor %}
I tried to figure out how to write the code to hide these products in a better way. I tried product.vendor like below but when I search for those products individually they are not hidden. The code:
{% for item in search.results %}
{% if product.vendor == 'thevendor' %}
{% else %}
{% include 'search-result' %}
{% endif %}
{% endfor %}
Can someone tell me what I'm missing here? It seems it doesn't know what product.vendor is but when I print out who the vendor is, it displays the vendor. I don't understand why it's not hiding the products that are associated with this vendor.
{% for item in search.results %}
{% if item.product.vendor == 'thevendor' %}
{% else %}
{% include 'search-result' %}
{% endif %}
{% endfor %}
This should work.

How can I check for more than 1 product with same name?

I need to check if there are two or more products with the same name so I can add an if/else statement. So I'm thinking along the lines of:
{% if product.title == product.title %}
or
{% if product.title.size > 1 %}
But this doesn't seem to be right.
Thanks!
Are you looking for a specific product title, or any product title that is duplicated? If you are comparing against a given product title, perhaps try something like this:
{% assign found_duplicate = false %}
{% for p in products %}
{% if p.title == product.title %}
{% assign found_duplicate = true %}
{% endif %}
{% endfor %}
{% if found_duplicate == true %}
...
{% endif %}

SHOPIFY: How can I check if ANY variant is out of stock

I sell t-shirts with multiple variants.
I would like to check if ANY of those variants is "Out of Stock". Then if ANY of the variants is "Out of Stock" display a message. (the same message, not matter what variant is out of stock)
I know this works to check stock of the FIRST variant:
{% if product.variants.first.inventory_quantity <= 0 %}
<p style="color:#ff0000">This item is currently out of stock.
Order today, and your item will be shipped in 4-6 weeks.</p>
{% case product.variants.first.inventory_quantity %}
{% when '0' %}
{% else %}
{% endcase %}
{% endif %}
But this only checks the first variant. Any help here would be greatly appreciated. I am open to handling this in javascript or liquid, but am fairly new to both.
Here is one surefire way... and you can twist this into whatever pretzels you desire.
{% for variant in product.variants %}
{% if variant.inventory_quantity == 0 %}
<h1>Damn Dawg, this variant be out of stock</h1>
{% else %}
... whatever....
{% endif %}
{% endfor %}
It sounds like if you only want this message printed once, then it applies to the product and not the variants themselves. In this case, just set a variable to true if anything is out of stock and you can thus print your message just once. The limit:2 suggestion is nonsensical.
eg:
{% assign out_of_stock = false %}
{% for variant in product.variants %}
{% if variant.inventory_quantity == 0 %}
{% assign out_of_stock = true %}
{% endif %}
{% endfor %}
{% if out_of_stock == true %}
<h1>Damn Dog, we're out of beers</h1>
{% endif %}
In 2021 there is an HasOutOfStockVariants attribute for GraphQL.