Django template rendering to itself - django-templates

I am trying to render the dictionary content using Django template like this
for example : result contain dictionary X
X={a:1,
b:1,
c:X(dictionary X again)
}
This could be any many places and at multiple levels
template : results.html, says something like following
{{a}}
{{b}}
{% if X.a %}
{% include results.html %}
{% endif %}
I thought that this would work but I get error saying
maximum recursion depth exceeded while calling a Python object
How could I resolve this?
Thank you

get rid of the c:X part in your dictionary X, you can't do that.
You can use X or properties included in it twice in your template, so there's no need for nested self-references in your dictionary.

Related

How to check if condition in django template part

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 %}

Is it possible to use a liquid "where" array filter with nested properties?

I'm trying to filter an array of blocks using block settings. I can filter by properties like "type" using the following syntax:
{% assign example = section.blocks | where: "type", "photos" %}
What I need to do is filter by block settings, something like this:
{% assign example = section.blocks | where: settings.collection, collection.handle %}
The above example is failing silently.
A note: Currently I am accomplishing what I need using a capture with a for loop and an if statement, and then assigning with a split — but the code is so bloated, and doing all that for a simple filter operation seems ridiculous. I find myself constantly feeling like I'm fighting with liquid, and I guess I'm hoping it might be just a bit more elegant than I'm giving it credit for.
I don't know much about Ruby, but it seems you can't pass nested properties with dot notation to the where filter. However, after seeing people accessing nested values using map, I tested mixing the two, and the map filter seems to work well for this case.
I have a boolean setting called default in my blocks, and I got the settings object for the last block with default set to true using this:
{% assign obj = section.blocks | map: 'settings' | where: 'default' | last %}
Of course, then you can't get data outside of the settings object that was extracted. For that I think you really would need to loop through the section.blocks and find filter manually using the if tag.
You are doing it wrong. where will work only at the root element. In your case section.blocks is the root element so where can be used for something like section.blocks.abcd_property.
Rough example: {% assign example = section.blocks | where: 'collection', collection.handle %} will load all section blocks having their collection property as collection.handle value
This will work
{% if settings.collection == collection.handle %}
{% assign example = section.blocks %}
{% else %}
{% assign example = '' | split: '' %}
{% endif %}
Previously used map which loses outer data but found string notation works with where for nested properties:
E.g., Using a posts collection where each .md file has the front-matter:
header:
isArchived: true
The following liquid snippet filters archived posts via header.isArchived:
{% assign archived = site.posts | where: "header.isArchived", true %}

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 %}

Shopify - Capturing a Metafield Value of the Last Added Collection with a Custom Template

I'm working on a theme where I've got several collections of clothing and I have created a custom collection template called 'seasonal', with the intent of using a custom background color for that specific type of collection.
I've achieved this by using metafields. It's working fine and I now have two seasonal collection pages - FW15 and SS16, with two different background colors,
I would now like to fetch the background color of the most recent 'seasonal' collection in another page of the theme.
This is where I'm stuck in. See the code below:
{% for collection in collections reversed %}
{% if collection.template_suffix contains 'seasonal' %}
{% assign seasonalCollectionColor = collection.metafields.c_f.Collection_Color | split: "|" %}
{{ seasonalCollectionColor[0] }}
{% endif %}
{% endear %}
This is outputting both seasonal collection colors:
#8DE5EB #FF7C1A
Instead of just the most recent one, which I'm trying to get by appending [0] to seasonalCollectionColor.
Any help on what am I doing wrong?
Thanks in advance!
You are in a loop. The loop has one condition you are triggering off of (contains seasonal). Hence you capture the result twice, and output it twice. You are not limiting your test to the condition of most recent.
If you were to try and test for the condition of most recent, what would that be? In your case, perhaps since you are traversing collections in a reverse order, the first occurrence is your most recent one.
So add a condition that if the condition is found, and you have set the seasonalCollectionColor to something, DO NOT set it again... just ignore any other values that match, and then you'll have only one value, the most recent one.

comparing custom template tag within if tag

i have a custom template tag that takes some argument and calculates the result.
I want to compare that value obtained from that custom tag with another variable.
Custom template tag(having three arguments)
{% price_for_pax service pax '' %}
variable :
{{service.price}}
What i want is
{% if service.price == price_for_pax service pax '' %}
do something
{% endif %}
When i look for the result it does not show anything
Can i compare like this ? If not what can be the solution ?
Thanks in advance
There were a couple of questions similar to this before:
Django - use template tag and 'with'?
django templatetags template , combine {{ }} method call with template tag context variable
Making a template filter rather than a template tag could do the trick.