dbt jinja "elif" functionality? - if-statement

According to the jinja documentation, a tag exists for the else if case within an if and else flow: Jinja Control Strucutures/IF
Looking for a way to do this within a dbt macro something like:
my_macro.sql
-- macros/my_macro.sql
{% macro my_macro() %}
{% if target.name == 'default' %}
select 'A' as my_letter;
{% elif target.name == 'dev' %}
select 'B' as my_letter;
{% elif target.name == 'qa' %}
select 'C' as my_letter;
{% elif target.name == 'prod' %}
select 'D' as my_letter;
{% else %}
select 1; -- hooks will error if they don't have valid SQL in them, this handles that!
{% endif %}
{% endmacro %}
If the elif tag or equivalent is unavailable, what are my options?
Something like the below only?
-- macros/my_macro.sql
{% macro my_macro() %}
{% if target.name == 'default' %}
select 'A' as my_letter;
{% else %}
select 1;
{% endif %}
{% if target.name == 'dev' %}
select 'B' as my_letter;
{% else %}
select 1;
{% endif %}
{% if target.name == 'qa' %}
select 'C' as my_letter;
{% else %}
select 1;
{% endif %}
{% if target.name == 'prod' %}
select 'D' as my_letter;
{% else %}
select 1;
{% endif %}
{% endmacro %}

Disregard the question above - it was an indentation issue.
{% elif %} tags work fine.

I often use elif in dbt jinja without issue. is there a reason you don't have this available?

Related

Django: Count forloop.first only if a second if condition is met

I have the following (oversimplified example):
{% for item in myitems %}
{% if item == "orange" %}
{{item}}
{% endif %}
{% endfor %}
Let's say that my list myitems is ['apple','orange','watermelon','orange']. The above code prints twice "orange". But I don't want this... I would like to print it once. So then I tried using if forloop.first
{% for item in myitems %}
{% if item == "orange" %}
{% if forloop.first %}
{{item}}
{% endif %}
{% endif %}
{% endfor %}
The first loop will be item=apple so it won't print the item because it is not "orange". In the second loop now we have item=orange but it no longer fulfills if forloop.first as it is the second loop already so it won't print the item. How can I print orange once? Is there a statement such us: if forloop.first (start numbering from the first print)
I think you can print the element of myitems only once when condition is met using a variable in the template and changing its value when the condition is met:
{% set stop_loop="" %}
{% for item in myitems %}
{% if stop_loop %}
{% elif item == "orange" %}
{{item}}
{% set stop_loop="true" %}
{% endif %}
{% endfor %}
IMO, this kind of business logics should be in the view rather than template.
If I've correctly understood, you're basically looking for this piece of code:
{% for item in myitems %}
{% if item == "orange" and forloop.first %}
{{item}}
{% endif %}
{% endfor %}
A simple and should do the job. With the example you provided ['apple','orange','watermelon'], the rendered template would be blank.
This is my solution based on previous comments
{% with False as stop_loop %}
{% for item in myitems %}
{% if stop_loop %}
{% elif item == "orange" %}
{{item}}
{% update_variable True as stop_loop %}
{% endif %}
{% endfor %}
{% endwith %}
And I need to register in templatetags the following:
#register.simple_tag
def update_variable(value):
return value
It works

Examine cart in Shopify

I'm hoping for some help with liquid in Shopify, I'm having trouble with trying to customise the cart based on what product the customer has added.
Basically if a customer adds product from Vendor A then I want the cart to load the template to customise the cart for Vendor A
But if product is from Vendor B then I want it to load the template to customise the cart for Vendor B
But if the cart has products from neither (or both) then I want it to load the default cart.
{Edit: I worked out what was wrong with my code to load the templates but now I just need help with the logic so that when the cart has products from both brands it loads the default cart. Because at the moment it loads both cart snippets into the page}
Any help massively appreciated!
{% for item in cart.items %}
{% if item.vendor == 'Brand A' %}
{% include 'cart-a' %}
{% elsif item.vendor == 'Brand B' %}
{% include 'cart-b' %}
{% else %}
{% section 'cart-default %}
{% endif %}
{% endfor %}
also tried this:
{% case cart.items %}
{% when item.vendor == 'Brand A' %}
{% include 'cart-a' %}
{% when item.vendor == 'Brand B' %}
{% include 'cart-b' %}
{% when item.vendor == ‘Brand A’ and item.vendor == 'Brand B' %}
{% section 'cart-default' %}
{% else %}
{% section 'cart-default' %}
{% endcase %}
I think this steps may help you...
Step 1: Create different section instead of snippets for two different types of vendors and default
Step 2: Follow the below code in cart.liquid
{% assign vendor = '' %}
{% assign same = true %}
{% for item in cart.items %}
{% if vendor != '' or vendor == item.vendor %}
{% assign vendor = item.vendor %}
{% else%}
{% assign same = false %}
{% endif %}
{% endfor %}
{% if same == true %}
{% if vendor == 'Brand A' %}
{% section 'cart-a' %}
{% elsif vendor == 'Brand B'%}
{% section 'cart-b' %}
{% else %}
{% section 'cart-default' %}
{% endif %}
{% else %}
{% section 'cart-default' %}
{% endif %}
In liquid it is easier to work with arrays. Working code for you:
{% assign vendors = cart.items | map: 'vendor'| uniq | join: ' ' %}
{% if vendors contains "Brand A" and vendors contains "Brand B" %}
{% section 'cart-default' %}
{% else %}
{% if vendors contains "Brand A" %}
{% section 'cart-a' %}
{% else %}
{% if vendors contains "Brand B" %}
{% section 'cart-b' %}
{% else %}
{% section 'cart-default' %}
{% endif %}
{% endif %}
{% endif %}

Invalid block tag 'set', expected 'empty' or 'endfor'. Did you forget to register or load this tag?

I work on Django 1.11 and in my template file I've got this code :
{% for article in all_articles %}
{% set color_category = 'light-blue' %}
{% if article.category == 'SEO' %}
{% color_category = 'light-blue' %}
{% elif article.category == 'SEA' %}
{% color_category = 'amber' %}
{% elif article.category == 'Python' %}
{% color_category = 'green' %}
{% elif article.category == 'Django' %}
{% color_category = 'light-green' %}
{% else %}
{% color_category = 'light-blue' %}
{% endif %}
{% endfor %}
And Django returned me this error :
Exception Type: TemplateSyntaxError
Exception Value:
Invalid block tag on line 12: 'set', expected 'empty' or 'endfor'. Did you forget to register or load this tag?
Have you got an idea ?
Ask if you need more info (like my settings file).
Thanks !
set is not a valid tag in django. You should use with if you want to define a variable in your template.
{% with color_category='light-blue' %}
Do stuff
{% endwith %}
However, it's always better to do this kind of operation in the view in python.
The solution above is correct, but with a minor mistake. There shouldn't be a space between the variable and its value, so the correct sintaxis should be:
{% with color_category='light-blue' %}
Do stuff
{% endwith %}

Multiple condition When statement in Big Cartel

I am trying to make a multiple condition statement on Big Cartel and I keep getting an error telling me that there is an unknown tag in my When statement. I feel like this is very simple. What am I doing wrong? Thank you for looking.
{% case product.status %}
{% when 'sold-out' %}
{% if product.id = '25027747' %}
RESULT 1
{% else %}
{% if product.id = '25027993' %}
RESULT 2
{% else %}
{% endif %}
You'll want to use this code:
{% case product.status %}
{% when 'sold-out' %}
{% if product.id = '25027747' %}
RESULT 1
{% elsif product.id = '25027993' %}
RESULT 2
{% endif %}
{% endcase %}

Django template {% if x.number == 0 %} does not work

This {% if x.number == 1 %} and {% if x.number == 2 %} work good
but {% if x.number == 0 %} does not work. Why?
{% for d in data %}
{% for x in d.animalnumber_set.all %}
{{ x.number }} <!-- Nothing displays. ->
{% if x.number == 1 %}
<p>Something</p>
{% endif %}
{% if x.number == 2 %}
<p>Something 2</p>
{% endif %}
{% if x.number == 0 %}
<p>Nothing</p>
{% endif %}
{% endfor %}
{% endfor %}
EDIT:
In database number filed is choices. How to replace {% if x.number == 0 %}? == None also does not work.
----
1
2
3
4
if the data has no value or 0, use not
{% if not x.number %}
If the avaialble choices are between 1-6, why do you check for x.number == 0? This will never occur.
If the user doesn't have any animalnumber the d.animalnumber_set.all will return None. So the control would be to check if x is empty
{% for d in data %}
{% for x in d.animalnumber_set.all %}
{% if x.number == 1 %}
<p>Something</p>
{% endif %}
{% if x.number == 2 %}
<p>Something 2</p>
{% endif %}
{% empty %}
<p>Nothing</p>
{% endfor %}
{% endfor %}