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:
- Flask’s built in templating with Jinja (
render_template
)
- 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.
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).
It looks like you’re attempting to use two different forms of replacement:
- Flask’s built in templating with Jinja (
render_template
) - 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.