Django Multi-Conditional Statement - html

I have the following code working in a Django HTML template. However, it’s quite repetitive. How can this code be simplified?
It translates to, "If you're not staff, you get to see nav.html. If you are staff, you only get to see nav.html if you're on these 4 pages."
{% if not request.user.is_staff %}
{% include ‘nav.html’ %}
{% else %}
{% if request.get_full_path == ‘/one/’ %}
{% include ‘nav.html’ %}
{% if request.get_full_path == ‘/two/’ %}
{% include ‘nav.html’ %}
{% if request.get_full_path == ‘/three/’ %}
{% include ‘nav.html’ %}
{% if request.get_full_path == ‘/four/’ %}
{% include ‘nav.html’ %}
{% endif %}
{% endif %}

From your view, you can send a list containing the paths for which to show nav.html. Something like,
allowed_paths = ['/one/', '/two/', '/three/', '/fourth/']
In your template, you can simply do,
{% if not request.user.is_staff or request.get_full_path in allowed_paths %}
{% include 'nav.html' %}
{% endif %}

Related

how to displayliquid code in Jeckyll post

Hello I am trying to make a post using jeckyll and as part of my post I would like to show some liquid code. The post should display the IF statement as part of the post text (example below).
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
I have tried to post this as
{% highlight liquid %}
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
{% endhighlight %}
and also
{% highlight markdown %}
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
{% endhighlight %}
but anything I try seems to be still executing the liquid code.
Is there a way to display the IF statement my post?
Try wrapping your liquid code in {% raw %} {% endraw %} like this:
{% highlight liquid %}
{% raw %}
{% if customer and customer.tags contains 'Wholesale' %}
{% endif %}
{% endraw %}
{% endhighlight %}
The raw tag will disable any liquid processing and output your code as desired.

Liquid/Jekyll: How to check for no posts when one has two or more conditions?

I am having trouble understanding how I might show a "no posts exist" message for a particular conditional statement with two variables.
In this example, let's say I have a collection of "animals" - on a particular page, I'd like a section that displays "primates that are herbivores":
{% for animal in site.animal %}
{% if animal.species == "primate" and animal.type == "herbivore" %}
{{ animal.content }}
{% endif %}
{% endfor %}
What I'd like to do is something like this (pseudocode):
{% if POSTS_EXIST_FOR_THIS_COMBO: (animal.species == "primate" and animal.type == "herbivore") %}
{% for animal in site.animal %}
{% if animal.species == "primate" and animal.type == "herbivore" %}
{{ animal.content }}
{% endif %}
{% endfor %}
{% else %}
There are no posts for this category.
{% endif %}
Note: This differs from examples like this, because I have two parameters to check. Can someone offer a suggestion about the syntax?
I think you can do the following where you at first filter all by species=primate from site.animal and then filter by type=herbivore from that pool and then check if the result exists.
{% assign animals = site.animal | where:"species","primate" | where:"type","herbivore" %}
{% if animals %}
{% for animal in animals %}
{{ animal.content }}
{% endfor %}
{% endif %}
Hope this helps.

Jekyll nested include with for loop

I'd like to use a {% for %} loop in an included file, to avoid repeating logic to create the loop array (it's an assign with multiple where_exps).
But I'd like to use different content depending on where I include the loop, so sometimes I will do this:
{% for i in a %}
<li>{{ i.name }}</li>
{% endfor %}
and sometimes:
{% for i in a %}
<loc>{{ i.url }}</loc>
{% endfor %}
How can I achieve this? So far I have to put each of the inner contents in their own template, so I would have files like below, but I'd like to avoid the extra template files, and just keep that content in the appropriate main file:
html_template.html:
<li>{{ i.name }}</li>
xml_template.xml:
<loc>{{ i.url }}</loc>
page_loop.html:
{% assign a = "logic I don't want to repeat" %}
{% for i in a %}
{% include {{ include.inner_template }} %}
{% endfor %}
html_main.html:
{% include page_loop.html inner_template="html_template.html" %}
xml_main.xml:
{% include page_loop.html inner_template="xml_template.xml" %}
It would probably be another more elegant (?) solution developing a plugin, but quickly modifying your code, in _includes/page_loop.html:
{% assign a = "something" %}
{% for i in a %}
{%if include.type == "name"%}
<li>{{ i.name }}</li>
{%else if include.type == "url"%}
<loc>{{ i.url }}</loc>
{%endif %}
{% endfor %}
Then each time you include page_loop.html pass an additional parameter specifying which type of output you want:
{% include page_loop.html type="name" %}
or
{% include page_loop.html type="url" %}

Nested "for" loop inside "if" condition in Liquid/Jekyll

I'm getting syntax error while trying to generate site. Do you have any ideas what can be wrong here?
Error: Liquid syntax error: Unknown tag 'elsif'
{% if page.title == "Tags" %}
{% for tag in site.tags %}
{% elsif page.title == "Categories" %}
{% for tag in site.categories %}
{% endif %}
{{ tag[0] }}
{% endfor %}
You can't start a loop conditionally like that, control blocks must be properly nested. To accomplish what you're trying to do you could do:
{% if page.title == "Tags" %}
{% assign data = site.tags %}
{% elsif page.title == "Categories" %}
{% assign data = site.categories %}
{% endif %}
{% for tag in data %}
{{ tag[0] }}
{% endfor %}
You have got it all wrong. The nested loops does not work this way.
It should start and end inside the same conditional.
if conditional
for loop
endfor
endif
something like this.
So, the correct way to do it should be this
{% if page.title == "Tags" %}
{% for tag in site.tags %}
{{ tag[0] }}
{% endfor %}
{% elsif page.title == "Categories" %}
{% for tag in site.categories %}
{{ tag[0] }}
{% endfor %}
{% endif %}
This code should do exactly what you want correctly but there is a better approach as answered by JJJ

Shopify liquid get related blog posts

In shopify I am using liquid templating to get blog posts which are related to products by their tags, like so:
<ul>
{% for article in blogs.blog.articles %}
{% if article.tags contains product.handle %}
<li><p>{{ article.title }}</p></li>
{% endif %}
{% endfor %}
</ul>
However, if there are no related posts, I would like to display a message such as "No related posts!"
My question is how would I do that? I have contemplated trying to get the articles into an array and testing if it is empty, but I am having difficulty finding out how this is done.
Thanks!
Try something like this:
{% assign related_posts = "" %}
{% for article in blogs.blog.articles %}
{% if article.tags contains product.handle %}
{% capture post %}
<li><p>{{ article.title }}</p></li>
{% endcapture %}
{% assign related_posts = related_posts | append:post %}
{% endif %}
{% endfor %}
{% if related_posts.size > 0 %}
<ul> {{ related_posts }} </ul>
{% else %}
No related posts!
{% endif %}
<ul>
{% for article in blogs.blog.articles %}
{% if article.tags contains product.handle %}
<li><p>{{ article.title }}</p></li>
{% else %}
<li>No related blog posts!</li>
{% endif %}
{% endfor %}
</ul>