How can I use literal list in Django template file? - django-templates

From a Django template file I want to check if my variable myVar is "A" or "B" (or "C" or "D", etc..).
So I would like to do something like this:
{% if myVar in ["A", "B"] %}
Hello
{% else %}
World
{% endif %}
But this gives me a syntax error in the first line.
How then can I use a literal list in the Django template file?

you can't define a list directly in the template. You could pass a list to the template using a view in views. py and a url in urls. py
ex:In views. py
def view_name(request):
list_name=['A', 'B', 'C'];
render(request, 'directory/template_name.html'
{'list_name':list_name})
In urls. py
urlpatterns = [
path('index/', views.view_name, name='main-view'),
]
In template
{% if myVar in list_name%}
Hello
{% else %}
World
{% endif %}

The answer can be found here: check for presence in a list django template
This question is essentially a duplicate.

Related

How to use a variable as a key in a hash in liquid (Shopify)

I would like to set up a hash variable using strings from an array dynamically (instead of writing 1000 lines of code).
As well I would like to use a dynamically created string to access a hash by using it as the key - for a built-in (what I assume is a hash) object - settings. Settings allow you to access data in settings_schema.json, eg: settings.my_custom_setting
According to this documentation: https://github.com/Shopify/liquid/wiki/Liquid-for-Designers
"For hashes, the key must be a literal quoted string or an expression that resolves to a string."
so I have tried {% assign filter[thisFilter] = false %} but get an error: ParseError: illegal token
First issue / accessing hash key with a variable:
{% comment %} All possible filters {% endcomment %}
{% assign allFilters = "color,size,collection,style,height,function,artist" %}
{% assign allFiltersArray = allFilters | split ',' %}
{% comment %} hash of filters each set to false {% endcomment %}
{% for thisFilter in allFiltersArray %}
{% assign filter[thisFilter] = false %}
{% endfor %}
Second issue, accessing settings object with a dynamically generated key:
{% comment %} set to true whichever filters are configured in settings for this collection {% endcomment %}
{% for thisCollection in allCollectionsArray %}
{% if thisCollection == currentCollection %}
{% for thisFilter in allFiltersArray %}
{% assign itemToCheck = "filter_" | append: thisCollection | append: "_" | append: thisFilter %}
{% if settings[itemToCheck] %}
{% assign filter[thisFilter] = true %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
In the first issue, I expect the result to be a hash such as:
filter['color'] = false (or filter.color = false)?
filter['size'] = false
In the second issue, I'm expecting something like:
{% if settings.filter_shirts_color %}
What you are trying to do is not possible. If you read further on your provided link Liquid for Designers, it is mentioned
Note that there is no way to write a literal array or hash as an
expression; arrays and hashes must be passed into the template, or
constructed obliquely with a tag or output statement.
Moreover, even if you have such hash, you cannot assign it new value. For example,
{% assign settings['some-setting-id'] = false %}
This will not work. Same is the case with array created using split filter. You cannot assign new values on any index.
For the second issue, this should work, the error in your case most probably is because of invalid generated string or there is no setting with that id. This should work fine and display value for that setting.
{%assign string_key = 'setting-key'%}
{{settings[string_key]}}
But this will not work because
{%assign string_key = 'setting-key'%}
{{settings.string_key}}
my_hash.key — Hashes also allow a shorter "dot" notation, where the
name of the variable is followed by a period and the name of a key.
This only works with keys that don't contain spaces, and (unlike the
square bracket notation) does not allow the use of a key name stored
in a variable.

Variable alias in a for cycle with Jinja2

I have this code inside my html:
{% for macchine in range(20) %}
{% set macchina_usata = 'M'+ macchine|string %}
{{ data['macchina_usata'] }}
{% if data['macchina_usata'] is defined %}
do something..
{% endif %}
{% endfor %}
before it was without the for cycle, I just had to check if a variable is defined and I got the result, but now I want to put it in a Cycle for because I have to check 20 or more variables.
The variables that I got from the previous html are like M1, M2, M3, ... M20 then I thought that was a good idea to create a varible macchina_usata composed by M+ the int macchine converted in a string, but when I try to print it nothing happen, so, i guess that I'm using the Alias in a wrong way
You're using the literal string 'macchina_usata' as an index for data. You should instead use variable macchina_usata, without the quotes:
{{ data[macchina_usata] }}
{% if data[macchina_usata] is defined %}

Using a string to create a Liquid variable

In my shopify store, I am using SuperFields in order to customize my site, though my question isn't about the app. On one of my pages, I need the value for the following:
variant.metafields.sf_{{ collection.title | downcase }}[meta_tag_key]
The value should be 0 or 1. If I evaluate the statement directly, such as:
{if variant.metafields.sf_{{ collection.title | downcase }}[meta_tag_key] =1%}
It throws an error when I render the page: Unexpected character '{'
I've also tried the following:
{% capture defaultImage %}variant.metafields.sf_{{ collection.title | downcase }}[meta_tag_key]{% endcapture %}
{% assign test = defaultImage %}
But 'test' is considered nil and doesn't return any value. I have tried to search for answers here and on the shopify forum, but, as my clumsy post title suggests, I'm having a hard time concisely searching for a solution to this problem. Any help is greatly appreciated.
You can try :
{% assign metafield-key = collection.title | downcase | prepend: "sf_" %}
{% assign key = variant.metafields[metafield-key][meta_tag_key] %}
{% if key == 1 %}
Do the twist !
{% endif %}
You are missing a % sign in your code. Hence the error message. Your if statement started with {% and not just {
If you working in liquid then you have to use {% %} for defining any variable & also for condition in shopify. You can't use { this.

how to split the string in django template?

i am trying to split the string in template using custom template filter. But i got an error
TemplateSyntaxError at /job/16/
'for' statements should use the format 'for x in y': for skill in form.instance.skills | split : ","
Here it is my filter
#register.filter(name='split')
def split(value, key):
"""
Returns the value turned into a list.
"""
return value.split(key)
this is my template
<h4>Skills</h4>
{% for skill in form.instance.skills | split : "," %}
{{ skill }}
{% endfor %}
Thanks
Split is a custom filter, don't forget to create your filter, and to load it in your HTML page.
Documentation for Django 4.0: https://docs.djangoproject.com/en/4.0/howto/custom-template-tags/
<h4>Skills</h4>
{% with form.instance.skills|split:"," as skills %}
{% for skill in skills %}
{{ skill }}<br>
{% endfor %}
{% endwith %}
For extract character string, use filter cut:
Phone
this removes the scripts from the string.
The direct for loop works too, you just have to remove the spaces in the syntax:
<h4>Skills</h4>
{% for skill in form.instance.skills|split:"," %}
{{ skill }}
{% endfor %}

using Liquid variables inside of a liquid tag call

I made a custom link tag in Liquid and I am trying to be able to pass liquid variables into the call for that tag like so
{{ assign id = 'something' }} // this value is actual dynamic while looping through data
{% link_to article: id, text: 'Click Me!' %} // my custom tag
However this results in the article parameter being passed in as 'id' instead of 'something' as per the assign statement above it.
Does anyone know how to pass variables into tag calls?
I've recently solved this very simply with Jekyll 0.11.2 and Liquid 2.3.0 by passing the name of the variable as the tag parameter.
{% assign v = 'art' %}
{% link_to_article v %}
You can also pass the name of the control var while in a loop, like article above.
In Liquid::Tag.initialize, #markup is the second parameter, the string following the tag name. The assigned variables are available in the top level of the context.
def render(context)
"/#{context[#markup.strip]}/"
end
This obviously only allows one param to be passed. A more complex solution would parse params like x: 2, y: 3.
This solved the case for me context[#markup.strip].
My problem was that i wanted to be able to pass a variable to my custom Liquid tag like this: {% get_menu main_menu navigation.html settings.theme.id %}
In order to do this i first split the variable string into different varaibles on every space character.
class GetMenu < Liquid::Tag
include ApplicationHelper
def initialize(tag_name, variables, tokens)
#variables = variables.split(" ")
#menu_object = #variables[0]
#file_name = #variables[1]
#theme_id = #variables[2]
super
end
def render(context)
# This is where i use context[#theme_id.strip] to get the variable of "settings.theme.id"
content = CodeFile.find_by(hierarchy: 'snippet', name: #file_name.to_s, theme_id: context[#theme_id.strip])
#menu ||= Menu.find_by_slug(#menu_object)
context.merge('menu' => #menu)
Liquid::Template.parse(content.code).render(context)
end
end
Liquid::Template.register_tag('get_menu', GetMenu)
*This is just a more rich example that the answer above by Jonathan Julian
Doesn't look like this is possible, my solution was to just pass the variable name in to the tag and grab it out of the context the tag is being rendered in. Like so:
{% for article in category.articles %}
{% link_to variable: article, text: title %}
{% endfor %}
in my tag code (condensed):
def render(context)
uri = "article/#{context[#options[:variable]]['id']}"
"<a href='#{uri}'>#{build_link_text context}</a>"
end
It would be great to have a tag that can be called with literals and variables like
{% assign v = 'art' %}
{% link_to_article v %}
or
{% link_to_article 'art' %}
or
{% link_to_article "art" %}
and also of course
{% link_to_article include.article %}
In order to so I propose a helper function
def get_value(context, expression)
if (expression[0]=='"' and expression[-1]=='"') or (expression[0]=="'" and expression[-1]=="'")
# it is a literal
return expression[1..-2]
else
# it is a variable
lookup_path = expression.split('.')
result = context
puts lookup_path
lookup_path.each do |variable|
result = result[variable] if result
end
return result
end
end
And in the render just call the helper function to get the value of the literal or variable.
def render(context)
v = get_value(context, #markup.strip)
end
FYI, the initialiser would look like this:
def initialize(tag_name, markup, tokens)
#markup = markup
super
end
This does not strictly answer the question, but it may help others who are new to Liquid (like myself) and try something like this. Instead of implementing a custom tag, consider implementing a custom filter instead. Variables are resolved before they are passed into filters.
Ruby code:
module MyFilters
def link_to_article(input, text)
"<a href='https://example.org/article/#{input}'>#{text}</a>"
end
end
Liquid::Template.register_filter(MyFilters)
Liquid template:
{% assign id = 'something' %}
{{ id | link_to_article: 'Click Me!' }}
Output:
<a href='https://example.org/article/something'>Click Me!</a>
You can also use variables as parameters. So the following would have the same output:
{% assign id = 'something' %}
{% assign text = 'Click Me!' %}
{{ id | link_to_article: text }}
And filters can have zero or more (comma-separated) parameters:
{{ 'input' | filter_with_zero_parameters }}
{{ 'input' | filter_with_two_parameters: 'parameter 1', 'parameter 2' }}