Do statement not working in jinja - python

I'm altering an existing web interface to view ROBOT doc libraries, which uses a mixture of jinja (Python inside HTML) and HTML. I have never worked with jinja or HTML before and am having issues getting even a simple test case to work. When the browser loads the docs, I want our project's directory structure for the docs to be preserved to make finding things easier, and so I want to use jinja to create the dir structure. Here is a snippet of the code I'm working with:
{% extends "base.html" %}
{% block body %}
<div class="well" id="left">
<ul class="list-group list-unstyled">
{% set collection_list = [] %}
{% for collection in data.hierarchy %}
{% if collection.collection_id|string == data.collection_id|string %}
{% do collection_list.append(collection.path) %}
{% else %}
{% for link in collection.path_chain %}
<li>
<label class="tree-toggler nav-header"
title="file path: {{collection.path}}">{{link}}</label>
<ul class="list-group tree collapse"
id={{link}}>
</ul>
{% endfor %}
</li>
{% endif %}
...there's more after that, but this is where I hit the error. It sets the collection_list var fine, and the if statements work, but when it goes to execute the 'do' statement it fails with:
TemplateSyntaxError: Encountered unknown tag 'do'. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.
I don't believe this is an unclosed loop or something because if I replace the do statement with a simple test print statement, it works. Does anyone know what I'm doing wrong?

From the template documentation:
Expression Statement
If the expression-statement extension is loaded, a tag called do is available that works exactly like the regular variable expression ({{ ... }}); except it doesn’t print anything. This can be used to modify lists:
{% do navigation.append('a string') %}
You need to enable the Expression statement extension for this to work.
You didn't show how you load the Jinja2 environment, but loading extensions takes place via the extensions argument to the Environment() class:
jinja_env = Environment(extensions=['jinja2.ext.do'])

Related

Django: TemplateSyntaxError-Could not parse the remainder

My template gets a queryset named qs.value sent from the views.py, I can display the value using {{qs.value}} anywhere in the template, but using it in an if statement raises an error.
{% if {{qs.value}} > 0 %}
<!--do something-->
<h3 class="text-success">{{qs.value}}</h3>
{% else %}
<!--do something else-->
<button class="btn btn-primary">Else</button>
{% endif %}
The error:
Could not parse the remainder: '{{qs.value}}' from '{{qs.value}}'
What am I doing wrong?
{{ }} are used to get the string representation of the variable/fuction. {% %} are used to make some code working. Both can read variables/functions as they are passed with context without any additional {{/{% inside them because they process given arguments directly.
This error usually means you've forgotten a closing quote somewhere in the template you're trying to render. For example: {% url 'my_view %} (wrong) instead of {% url 'my_view' %} (correct). In this case it's the colon that's causing the problem. Normally you'd edit the template to use the correct {% url %} syntax.

How to use jinja tag inside jinja tag

This is my code:
{% if {{post.author.profile.image.url}} is None %}
When I run this code I get an error
Could not parse the remainder: '{{post.author.profile.image.url}}' from '{{post.author.profile.image.url}}'
How to solve this? And how to use a template tag inside a template tag
Use the value of expression directly, you shouldn't wrap it inside braces:
{% if post.author.profile.image.url is None %}
...
{% endif %}
abdusco's already answered the first part of your question ("how to solve this").
wrt/ the second part:
how to use a template tag inside a template tag
The simple answer is: you can't, period. Why it's not possible becomes rather obvious once you understand how the template system works, and that would be mostly useless anyway (if you find yourself trying to use a tag within a tag then you're doing it wrong and there's a better way, really).
NB: when I say you can`t nest tags, I mean that you can't do this:
{% sometag arg={% some_other_tag %} %}
Now in your example, what you're trying to do is not "using a tag inside a tag", but using a context variable within a tag, and this is of course possible (else the template language would be rather hard to use), as shown in abdusco's answer. And you can also use filter expressions (apply a filter to a context variable) here, ie {% mytag some.variable|upper %}, at least if the template tag is correctly implemented.
The first question has already answered. Regarding to this one:
And how to use a template tag inside a template tag
Short answer: you can't. Long answer: you can with help of the 'block assignment' tag ( http://jinja.pocoo.org/docs/2.10/templates/#block-assignments ) :
{% set somevar %}
... any number of tags here {{ post.author.profile.image.url }} ...
{% endset %}
...
{% if somevar is None %} ... {% endif %}
You can also (since Jinja2 2.10) apply filter to the assignment:
{% set somevar | default('Empty') %}
... any number of tags here {{ post.author.profile.image.url }} ...
{% endset %}

Replace all {{ and }} without replacing {{ special_str }} in python [duplicate]

I serve dynamic pages from Jinja2 templates in Flask. Now I am defining client-side templates in say, Jinja2-clone Nunjucks inside a script tag. Problem is, the client-side templates has syntax like <% %> that Flask's Jinja2 interpreter may interpret instead of rendering verbatim.
How can I make the entire block of scripts render verbatim?
You can disable interpretation of tags inside a {% raw %} block:
{% raw %}
Anything in this block is treated as raw text,
including {{ curly braces }} and
{% other block-like syntax %}
{% endraw %}
See the Escaping section of the template documentation.

Tornado Templating with {% code %} {% end %}

Is there any option to extend the tornado web template with the option inside the html template
{% code %}
# Python code
{% end %}
No, there is no such option. Tornado's templates are fairly liberal in allowing python code directly in the template, especially with the {% set %} directive (which can include any single-line statement, not just a variable assignment), but it is not possible to use multi-line statements except for the ones that have corresponding template directives ({% for %}, {% if %}, {% try %}, and {% while %})

Is there an equivalent of the "blocktrans" in tag in jinja2?

I am using jinja2 with my django application, I am working on porting some existing django templates over to jinja2. For the most part I am not having any issues; however, I have a statement like so in one of my django templates:
{% blocktrans %}
<p>Some stuff here</p>
{% endblocktrans %}
This causes jinja2 to become very unhappy. I have looked far and wide to see if there is an equivalent of the "blocktrans" tag for jinja2. All I can find is that enabling gettext let's you use:
{{ trans("Some String") }}
This is useful for short strings like in the title tag, but not for blocks. What am I missing, any help would be appreciated!
Use {% trans %} and its complement {% endtrans %} once the i18n extension is enabled.

Categories

Resources