How can I prevent escaping characters in Bottle - Python Web Framework?
I'm making a songs lyrics webapp in Bottle (python), and I'm testing all the data is correct before inserting it to the database, so, for now, I basically have a form that has "song name", "artist", "lyrics" (in a textarea) and that's it.
When the form submits it loads a page containing the three input values mentioned above (song, artist and lyrics) and everything is working as expected but the lyrics' html is being escaped (before sending the lyrics to the template I replaced all the \n
with <br>
).
So I did my research and from this tutorial from bottlepy.org and found that Bottle escapes the html tags to prevent XSS attacks and you can disable this by putting a "!" before the variable name, AWESOME! I found the solution, but... when I tried to use it it threw an error:
Exception:
SyntaxError('invalid syntax', ('H:\\Server\\htdocs\\letras\\prueba.tpl', 4, 27, "u'<div>Letra: ', _escape( !letra['letra'] ), u'</div>'])\n"))
Traceback (most recent call last):
File "H:\Server\htdocs\letras\bottle.py", line 764, in _handle
return route.call(**args)
File "H:\Server\htdocs\letras\bottle.py", line 1575, in wrapper
rv = callback(*a, **ka)
File "index.py", line 41, in guardar_letra
return template('prueba.tpl', letra = data)
File "H:\Server\htdocs\letras\bottle.py", line 3117, in template
return TEMPLATES[tplid].render(kwargs)
File "H:\Server\htdocs\letras\bottle.py", line 3090, in render
self.execute(stdout, kwargs)
File "H:\Server\htdocs\letras\bottle.py", line 3078, in execute
eval(self.co, env)
File "H:\Server\htdocs\letras\bottle.py", line 185, in __get__
value = obj.__dict__[self.func.__name__] = self.func(obj)
File "H:\Server\htdocs\letras\bottle.py", line 2977, in co
return compile(self.code, self.filename or '<string>', 'exec')
File "H:\Server\htdocs\letras\prueba.tpl", line 4
u'<div>Letra: ', _escape( !letra['letra'] ), u'</div>'])
^
SyntaxError: invalid syntax
from bottle import Bottle, route, run, template, static_file, get, post, request, response
from passlib.hash import sha256_crypt
import MySQLdb as mdb
import time
import re
@get('/enviar')
def enviar_letra():
return template('enviar_letra.tpl')
@post('/enviar')
def guardar_letra():
titulo = request.forms.get('titulo').capitalize() # Gets the song title from the form
artista = request.forms.get('artista') # Gets the artist
letra = request.forms.get('letra') # Gets the lyrics
fecha_envio = time.strftime('%Y-%m-%d %H:%M:%S') # Date the lyrics were sent
titulo = re.sub('[^\w|!|\s|\.|,]', '', titulo) # I delete every character except: words, exclamation, spaces, dots, commas
url = titulo + "-" + artista # concatenate the song's title and the artist name to make a nice url
url = re.sub('\W+|_', '-', url).lower() # lower all the characters from the url
url = url.strip("-") # strips "-" at the beginning and the end
letra = letra.replace("\n", "<br>") # replaces \n from the lyrics text area with <br>
data = { "titulo": titulo, "artista": artista, "letra": letra, "url": url, "Fecha_envio": fecha_envio } # song dictionary
return template('prueba.tpl', letra = data) # loads prueba.tpl template and send "data" dictionary as "letra" (letra is lyric in spanish)
run(host='localhost', port=8080, debug=True)
<h1>Letra de {{ letra['titulo'] }}</h1>
<h2>Por: {{ letra['artista'] }}</h2>
<div>Fecha: {{ letra['Fecha_envio'] }}</div>
<div>Letra: {{ !letra['letra'] }}</div>
Here's how it works/looks if I let Bottle escape my lyrics html (notice how <br>
is being displayed as plain text):
http://i.stack.imgur.com/fxz7o.png
And finally, this is how ITS SUPPOSED to look
http://i.stack.imgur.com/6b58J.png
You need to place the exclamation mark right after the opening {{
for bottle to recognize it:
<div>Letra: {{! letra['letra'] }}</div>
Preferably, you want to omit the spaces there altogether, to be on the safe side:
<div>Letra: {{!letra['letra']}}</div>
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