flask and Jinja2 control structure doesn't work with render_template.format but works when passing the variable directly

Question:

Here is a MRE.

templates/index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Flask App</title>
  </head>
  <body>
    {{test}} {% if test %}lol{% endif %}
  </body>
</html>

my_test.py:

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html", test=True)


if __name__ == "__main__":
    # local run
    app.run()

This works perfectly.

However, when using the .format syntax, to output a variable I need to do {test} instead of {{test}} (which is fine, i don’t mind) but more importantly, the {% if ...}{% endif %} doesn’t work anymore. Any reason why? I can’t understand the difference and I don’t know how to google it (I’ve tried reading https://flask.palletsprojects.com/en/2.0.x/templating/ but I’m not sure I got any answer).

My question is to have an explanation of why this behaves like this. I evidently do know how to make the %if% works but my whole project uses .format() and I was wondering if I really needed to change everything and if there wouldn’t be any drawbacks* in doing so.

*EDIT: I found that if I did {my_variable} with my_variable containing a <br> it used to do a linebreak but with {{my_variable}} (not using .format), the <br> literally appears. So I guess, I’m not actually finding a way to make it work and I need some help.

EDIT2:
By using .format() I mean:

def index():
    return render_template("index.html").format(test=True)

and index.html would look like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Flask App</title>
  </head>
  <body>
    {test} {% if test %}lol{% endif %}
  </body>
</html>

and the if statement won’t work (test will be displayed correctly though).

Answers:

It looks like you’re attempting to use two different forms of replacement:

  1. Flask’s built in templating with Jinja (render_template)
  2. Python’s built-in format method for strings.

You likely want to do one or the other, not both. For constructing an HTML page, #1 is the better option (though you can do some wild things with just format), Jinja is purpose built for this task and allows you to do additional things, e.g. conditionals (if/else), loops, etc. Those are all constructs that are valuable when constructing HTML that format doesn’t support.

Answered By: Michael Boselowitz
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.