Why is this elsif not working? [Shopify] - if-statement

I have an if statement which works perfectly.
However, when I add an elsif into the mix only if runs and the elsif just works no matter what. The syntax highlighting doesn't work i.e the contains doesn't go bold and the tags in product.tags doesn't italicise.
{% if customer.tags contains 'Approved' %}
Show approved task.
{% elsif customer.tags contains 'Waiting Approval' %}
Show waiting approval task.
{% endif %}
The syntax highlighting doesn't work on the elsif when editing in the Shopify liquid editor. Which it should do.
What may be the problem here?
I can't use {% else %} here, because I need to specifically look for one or the other, as there are other tags used, which wont be used in this instance.

No Idea why the syntax wont work for your, the documentation looks like elsif should work. https://help.shopify.com/en/themes/liquid/tags/control-flow-tags
However, your logic should be fine if you do:
{% if product.tags contains 'Approved' %}
Show approved task.
{% endif %}
{% if product.tags contains 'Waiting Approval' %}
Show waiting approval task.
{% enfid % }
-> These are 2 ifs. But you said "look for one or the other" - if only one condition can be true, it's fine.

Related

How to truncatechars of wagtail streamfield block?

After reading all the docs, I still don't know how to truncatechars of a wagtail streamfield blocks.
{% for block in post.body %}
{% if block.block_type == 'richtext' %}
{{ block.value|truncatechars:100 }}
{% endif %}
{% endfor %}
works with weird results depending on quantity of truncatechars - if it's definitely above the number of characters of all the streamfields, it displays everything (all) as expected; Now i'm putting 40 and it displays:
First rich…
third ric…
fifth …
(my text streamfields are "first richtext", "third richtext" and "fifth richtext" ; second and third blocks are pics successfully filtered out )
I think it could be fixed by adding all of the blocks into one for output, but I don't know how to do it. Do I iterate ? There's no "+" tag :/
{{ post.body|first|truncatechars:200 }}
Is a working temporary fix, it isn't perfect because now I need to force admins to make their first streafield block a text and make it of enough length.

How to indent Django templates properly

I work in SublimeText 3. When writing Django templates I have a mixture of html and functions.
I like to indent my code so that block, if and other such statements are indented. For example:
Manual formatting
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
{% endblock %}
However, when I run any autoformatter HTML-CSS-JS-Prettify it ignores these brackets and treats them as text:
After formatting
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
{% endblock %}
Although plugins like Djaneiro give great tag highlighting, I haven't been able to find a way to get SublimeText to treat these as tags.
Has anyone had any luck?
This is a late answer, but I would like to mention a Django template formatter that I've created myself: DjHTML. You can install it using pip install djhtml.
Let's say template.html contains the following:
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
<script>
$(function() {
console.log("Password changed!");
});
</script>
{% endblock %}
Then running djhtml template.html will give the following output:
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
<script>
$(function() {
console.log("Password changed!");
});
</script>
{% endblock %}
It's easiest to use DjHTML as a pre-commit hook, so that templates will be automatically indented when you run git commit. Instructions on how to configure pre-commit can be found in the README.
There isn't one for sublime text as far as I can tell. I have no source I can quote on this, but I have basically searched nothing came up.
This discussion is by any means old, but active. I found this really old ticket about formatting standards for Django and it has been updated 9 Months ago to basically say they are "in favour of standards" and the proposed formatting for templates would be:
<ul>
{% for x in y %}
<li>{{ x }}</li>
{% endfor %}
</ul>
They also made a place happen that holds information about formatting guidelines in Django.
You might find this discussion interesting as well. It's old too, but it highlights the confusion about formatting in Django and the DIY solutions people came up with to cope.

Django nested templates

In trying to keep with DRY, I'm setting up my Django project HTML files now. I have successfully extracted most repeated information to my base.html page. On most (but not all) of my pages, my content is displayed within a general 'panel' which is basically just a container set-up with styling, but it's got a few div-tags to it so it looks a bit ugly and I'm having to type out the exact same code out several times on each page.
My idea was to extract this to a 'panel.html' then call it whenever I need it, for example some pages might just have one 'panel' whereas my dashboard (it's an administrative site) will have maybe 15+. So it seemed a better idea and cleaner to not have to type out all this code each time I need to set up a 'panel'.
My ideal page would look something like..
{% extends 'base.html' %}
{% block content %}
{% extends 'panel.html' %}
{% block panel_content %}
Panel content...
{% endblock panel_content %}
{% extends 'panel.html' %}
{% block panel_content %}
Second panel content
{% endblock panel_content %}
{% endblock content %}
I know I can't use extends multiple times but I'm using it just as an example for what it is I'm trying to achieve.
I am going to potentially have hundreds of these identical 'panels' across my site but each containing different content and it would be so much cleaner if I could just have one stored somewhere in a HTML file and call it however many times I need.
Is there a way to do this?
You can use include
{% include "panel.html" %}
I should mention that too many include statements create a performance issue.

Parsing and using list item content via Twig

I am experimenting with using Grav to create my next website. One of the things I would be able to do is to build a unordered list using data provided in Grav frontmatter from the Grav page that uses the template. Here is how I am trying to do this
---
sectionone:
listitems: "['Benefit 1','Benefit 2','Benefit 3']"
---
and then in the template somehow do the following
{% block featurelist %}
<ul>
{% set items = {{page.header.sectionone.consumers.benefits|json_decode}} %}
{% for item in {{}} %}
<li>{{item}}</li>
{% endfor %}
</ul>
{% endblock %}
However, Twig does not like this and reports back an error along the lines of
Twig_Error_Syntax
A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "punctuation" of value "{".
with the offending line being my {% set items = ... } statement. I am clearly doing something wrong here but I am a Twig newbie so I fail to see what that might be.
{% block featurelist %}
<ul>
{% set items = page.header.sectionone.consumers.benefits|json_decode %}
{% for item in items %}
<li>{{item}}</li>
{% endfor %}
</ul>
{% endblock %}
I figured this out eventually. Grav documentation is by and large very good. However, the documentation on page headers/frontmatter appears to be somewhat incomplete. There is no full description of the entire syntax that is understood by the frontmatter processor. In order to define an array in front matter all you need to do is the following
---
sectionone:
benefits:
- 'Benefit 1'
- 'Benefit 2'
- ...
---
In essence the standard markdown syntax for an unordered list. Grav's twig processor appears to convert this to a PHP array - no parsing required!

How do I DRY up common text in a Django template?

I have some static text that needs to show up at 2 locations within a template.
For example:
<div>
{% if something %}
This is a static text
{% else %}
Something else happened
{% endif %}
</div>
... more html
<span>
{% if something %}
This is a static text
{% else %}
Something else happend
{% endif %}
</span>
I can do the above by duplicating the above text at 2 different locations in my template file(as shown above).
I could also create a model which will store the text(This is DRY but cost a call to the DB for a simple task)
I'm thinking of using include template but that's probably not the best way to achieve my goal.
What's the best way to do it?
Definitely use Inclusion Tags:
http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags
The tag file would either be something super simple like just the text "This is a static text" or the entire block:
{% if something %}
This is a static text
{% else %}
Something else happened
{% endif %}
"something" can be passed as a variable to the template tag so you can use that entire block in a variable way.
I use the django internationalization to do that. So in my apps/template I just write the key, and in the .po files is the value of the keys.
{% load i18n %}
<div>
{% if something %}
{% trans "static" %}
{% else %}
{% trans "something else" %}
{% endif %}
</div>
And in my .po file:
msgid "static"
msgstr "This is a static text"
msgid "something else"
msgstr "Something else happened
Besides useful for multi-language, it's much easier for copy writing just in case you want to change it in the future because you can just look unto one file instead of browsing several templates.
There are several ways, but it probably depends on what the text is and how often it will be used. It's hard to recommend a specific choice without full details
Create a custom template tag (this one makes the most sense based on how you've described your problem above).
Create a base template which has the text in it at the correct location and then inherit off of it for your "2 locations"
Put the static piece of text in a settings file and pass it to the template renderer via Context (probably not the best idea, but depending on what you're doing it could be a possibility)
You could use flatblocks : http://github.com/zerok/django-flatblocks
or chunks : http://code.google.com/p/django-chunks/
Those may be overkill for your problem, since they store your snippets in the database, but they add the benefit of making it possible to edit them via the admin.
{% load chunks %}
<div>
{% if something %}
{% chunk "something" %}
{% else %}
{% chunk "something_else" %}
{% endif %}
</div>
There are lots of forks or similar projects, for example:
http://bitbucket.org/hakanw/django-better-chunks/
http://github.com/bartTC/django-generic-flatblocks
I have a file like Java properties that I use for all of my resource strings. I just serve up the one that I want. Keeping these in one place also makes translating easy.
Ex.:
welcome_msg="hello user!"
thank_you="thank you"
goodbye_msg="goodbye, " + thank_you
If the included text gets bigger, use an 'include' tag.
{% include "myapp/helptext.html" %}
GrtzG