Could not parse the remainder: '{{ list[loop.index0] }}' - python

I followed instructions in simmilar thread like: How do you index on a jinja template?
but my html template is not working and whole django project is not responding due to this.
Error that I'm getting:
Error during template rendering.
Could not parse the remainder: '[loop.index0]' from 'songs_titles[loop.index0]'
My code looks like this:
{% if converted_files_urls %}
<p>Titles: {{ songs_titles }}</p>
{% for n in converted_files_urls %}
<a href="{{ n }}" download>Download: {{ songs_titles[loop.index0] }}</a>
<br/>
{% endfor %}
{% endif %}
and the {{ songs_titles }} renders as list, so at least till here it works ok.
What am I doing wrong?

Actually you are looking for Jinja, that will not work on django.
In django template tag you should use forloop.counter0 and list indexing looks like
{{songs_titles.1}}
Need to set count in variable and then use it, for setting variable you could use -
{% with index=forloop.counter0 %}
{{ songs_titles.index}}
{% endwith %}
Still If you have any doubts you can comment it.

I finally resolved this by creating a custom template tag like here:
https://djangosnippets.org/snippets/2740/
But to be honest it sucks that that's the simplest working solution for now :/

Related

What {% %} and {{ }} mean in HTML?

I have recently started to learn Django, so I came across with some HTML templates, but those are pretty unfamiliar for me, they mostly consist of {% and {{
For example:
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
Vote again?
What are they? Implementations from other languages or HTML syntax? I'd be happy to get some docs, websites or examples too.
The {% _________ %} are template tags. They are used to interpolate a tag into the space. Examples include extend, include, and load to name but a few. They often extend, insert, or give some sort logical functionality in some way (if conditions or loops, etc).
The {{ ___________ }} syntax is for template variables. This is used to interpolate a variable declared either as one of the built-in options or your own which you have created from any number of methods (models, view context, etc).
The Django docs are pretty thorough with use cases of all these. Another website which shortlists these to make them readily understandable is https://www.djangotemplatetagsandfilters.com/
It doesn't mean anything in html itself, it means something in Django template language. For example:
{{ choice.choice_text }}
will substitute value of that variable during template rendering.
The other one {% and %} is used for template processing, for example to indicate to template processor that some task needs to be completed. Good example is:
{% if error %}
{{ error }}
{% endif %}
That means that the variable error will be displayed (rendered) only if it exists, or to be more precise if it has some value.
The ones you are referring are jinja codes. They are very essential to work with Django and also they easy to understand when you have general understanding about python and django. You can find the documentation about jinga in this URL Jinja2 Documentation

slice requires 2 arguments, 1 provided

I'm trying to add some values from another list synchronously in the for loop of django ’s template. When I use a given number everything works fine, but when I replace it to {{forloop.counter}} it reports an error slice requires 2 arguments, 1 provided
I Googled it and the suggestion is that there should be no spaces in the code, but there are no spaces in my code, here the code in question.
{% for i in invtypes %}
<li>
...
<p>{{data|slice:":{{forloop.counter}}"}}</p>
</li>
{% endfor %}
The {{data}} is a list of extra data for invtypes so they have same length and sort。
I added a colon after slice to fix the error.
Before:
{{ post.body|slice":200" }}
After:
{{ post.body|slice:":200" }}
The problem is that in the line {{data|slice:":{{forloop.counter}}"}} the ":{{forloop.counter}}" would not work as you expect as if it were performing string interpolation. What can be done to get around this is to use the with template tag along with the add and stringformat template filters to get the required value as a template variable before you try to render that:
{% for i in invtypes %}
<li>
...
{% with str_counter=forloop.counter|stringformat:"i" %}
{% with slice_var=":"|add:str_counter %}
<p>{{ data|slice:slice_var }}</p>
{% endwith %}
{% endwith %}
</li>
{% endfor %}
One should also note that a need to do this implies that the view is not supplying the data to the template in an efficient manner, ideally the template should not be doing all of this manipulation with data. It can be seen that invtypes and data have some type of relationship but the context given by the view does not convey that at all.
I had the same problem and the solutions seems to be spaces indeed.
Try:
{% for i in invtypes %}
<li>
...
<p>{{ data|slice:":{{ forloop.counter }}" }}</p>
</li>
{% endfor %}
and see how that goes.
I found the correct solution.
(Wrong) =>
{{data|slice: ":{{forloop.counter}}"}}
[don't add a space after slice's colon.
(Right) =>
{{data|slice:":{{forloop.counter}}"}}
If you add a space after slice's colon, it takes only the part which comes before that space and considered it as one argument and second one will be considered as missing.

How to slice a list in Django template?

I'm doing some pagination in Django. I want to show the pages' number which are ahead of the current page. I am using the following code:
{% for page in blogs_page.paginator.page_range|slice:"0:{{ blogs_page.number }}" %}
But this seems useless; the result does the same as the following:
{% for page in blogs_page.paginator.page_range %}
The slice does not work here. How do I fix this?
Never use {{ }} inside of {% %}, don't do this {% {{ }} %}.
{% for page in blogs_page.paginator.page_range|slice:"0:blogs_page.number" %}
I think it won't work. If I were you I would create a custom tag and executed all the logic there. So, it will look like this:
Template:
{% custom_tag blogs_page as result %}
{% for page in result %}
templatetags/tags.py:
from django import template
register = template.Library()
#register.simple_tag
def custom_tag(bl_page):
return bl.page.paginator.page_range[0:bl_page.number]
Details: custom tags

How do you declare python variables within flask templates?

I've got some basic experience building websites using a LAMP stack. I've also got some experience with data processing using Python. I'm trying to get a grip on the mongodb-flask-python thing, so I fired everything up using this boilerplate: https://github.com/hansonkd/FlaskBootstrapSecurity
All is well.
To experiment, I tried declaring a variable and printing it...
I get this error message:
TemplateSyntaxError: Encountered unknown tag 'x'. Jinja was looking for the following tags: 'endblock'. The innermost block that needs to be closed is 'block'.
Here's my main index.html page
{% extends "base.html" %}
{% block content %}
<div class="row">
<div class="col-xs-12">
Hello World, at {{ now }}, {{ now|time_ago }}
</div>
</div>
<div class="row-center">
<div class="col">
{% x = [0,1,2,3,4,5] %}
{% for number in x}
<li> {% print(number) %}
{% endfor %}
</div>
</div>
{% endblock %}
I love learning new things, but man, can I ever get hung up for hours on the simplest of things... any help would be greatly appreciated!!!
Flask uses Jinja as its default templating engine.
The templating language is python-esque, but is not python. This is different from something like a phtml file, which is php interspersed with html.
Check the jinja documentation for more of what you can do, but here's how you set a variable within a template:
{% set x = [0,1,2,3,4,5] %}
http://jinja.pocoo.org/docs/2.9/templates/#assignments
Try this:
{% set x = [0,1,2,3,4,5] %}
See Jinja docs.

How to dynamically add items to jinja variable in Flask?

I'm building a website using Flask with its jinja2 templating engine and I'm dynamically building the menu (as described here):
{%
set navigation_bar = [
('/', 'index', 'Home'),
('/aboutus/', 'aboutus', 'About Us'),
('/faq/', 'faq', 'FAQ')
]
%}
{% set active_page = active_page|default('index') -%}
<ul>
{% for href, id, title in navigation_bar %}
<li{% if id == active_page %} class="active"{% endif %}>
{{ title|e }}
</li>
{% endfor %}
</ul>
Now if a user is logged in I want to show some additional things. So at runtime I want to add items to the navigation_bar variable. I tried something like this:
{% if g.user.is_authenticated() %}
{% navigation_bar.append(('/someotherpage', 'someotherpage', 'SomeOtherPage')) -%}
{% endif %}
But unfortunately this results in the following error: TemplateSyntaxError: Encountered unknown tag 'navigation_bar'. Jinja was looking for the following tags: 'endblock'. The innermost block that needs to be closed is 'block'.
So: does anybody know how I can add additional items to a jinja2 variable at runtime? All tips are welcome!
[bonus question]
I was also wondering, what does the - do at the end of {% set active_page = active_page|default('index') -%}?
The error occurs because Jinja can't identify block. Each Jinja block should start from block name. do block from do extension meets your needs. To use it you should add
do extension to jinja extensions. You can do this like so:
app.jinja_env.add_extension('jinja2.ext.do')
And then you can use do extension. Your example should looks like this:
{% if g.user.is_authenticated() %}
{% do navigation_bar.append(('/someotherpage', 'someotherpage', 'SomeOtherPage')) %}
{% endif %}
Here's another simple example.
You will find answer to your bonus question here. In short - removes whitespaces from start or end of block (this depends on where it is located).
To complete the answer of Slava Bacherikov, if you don't have the Jinja "do extension", you can use the tag set:
{% if g.user.is_authenticated() %}
{# use a dummy variable name, we juste need the side-effect of method call #}
{% set _z = navigation_bar.append(('/someotherpage', 'someotherpage', 'SomeOtherPage')) %}
{% endif %}

Categories