8

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?

Obito
  • 391
  • 3
  • 8

1 Answers1

18

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'])
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Ah, I see - I didn't realize it wasn't included. Sorry about that, I'll track down where in the code it gets loaded and add the extension. – monkeyWithAMachinegun Oct 04 '16 at 18:10
  • 3
    To load this extension in a Flask app, add `app.jinja_env.add_extension('jinja2.ext.do')` somewhere during app initialization. – Lucas Werkmeister Oct 20 '18 at 16:28
  • Maybe there is no way around this but, its causing white space to be spit out `{% do navigation.append('a string') %}` Its not outputting None, but I have a good chunk of just newlines now, which I would prefer not to have. – Melendowski Nov 20 '20 at 16:45
  • @Melendowski: Jinja gives you [plenty of control over whitespace](https://jinja.palletsprojects.com/en/2.11.x/templates/#whitespace-control); use `{%-` instead of `{%` to remove whitespace before the block, and using `-%}` instead of `%}` will remove any whitespace following the block. – Martijn Pieters Nov 20 '20 at 21:56