Lets say i have the following script in a html template of a flask application
<script type="text/javascript">
console.log('{{ url_for('root', arg1='hello', arg2='world') }}')
<script>
and i have a flask endpoint root()
@app.route('/', methods=['GET'])
def root():
print(print(request.args))
when i call my page the internal script is rendered to
console.log('/api/art_structure?arg2=world&arg1=hello')
When I call this url my request.args
dict is:
ImmutableMultiDict([('amp;arg1', 'hello'), ('arg2', 'world')])
Which is not correct since the key of arg1
is wrong.
Any clues how I can prevent jinja2 from converting &
to &
?
The ampersand
The correct URL is /api/art_structure?arg2=world&arg1=hello
.
The problem with the above URL is that ampersand (&
) cannot be written directly in HTML, because the ampersand is used for entity references. For example, to write <
character in HTML, which is not a tag start, one can write <
. Because of that, to write &
, one should escape it, i.e. write it as &
.
Jinja2 templating engine does that by default. So, you can dump the contents of any string variable even if it contains special characters and they will be correctly escaped, e.g. &
will become &
as in your case.
How does that work?
So, if you actually put this in your jinja template: <a href="{{ url_for('root', arg1='hello', arg2='world') }}">link</a>
, it would write the following HTML code: <a href="/api/art_structure?arg2=world&arg1=hello">link</a>
, and if you clicked on the link in the browser, it would correctly replace &
with &
and open /api/art_structure?arg2=world&arg1=hello
.
(note, however, that writing plain &
as it is into HTML may sometimes also work, because browsers may guess how to fix the error)
So why does it not simply work in this case?
Because you are generating JavaScript and not HTML (you are generating code within <script>
and </script>
. In JavaScript, &
is fine and should not be escaped, so you are free to write it as it is. To tell Jinja that you do not want it to escape the string, you can use the safe
filter, i.e. {{ url_for('root', arg1='hello', arg2='world') | safe}}
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With