I wrote this little function for writing HTML tags:
def html_tag(tag, content=None, close=True, attrs={}):
lst = ['<',tag]
for key, val in attrs.iteritems():
lst.append(' %s="%s"' % (key, escape_html(val)))
if close:
if content is None: lst.append(' />')
else: lst.extend(['>', content, '</', tag, '>'])
else:
lst.append('>')
return mark_safe(''.join(lst))
This worked fine, but then I read this article on efficient string concatenation (I know it doesn't really matter for this, but I wanted consistency) and decided to update my script:
def html_tag(tag, body=None, close=True, attrs={}):
s = StringIO()
s.write('<%s'%tag)
for key, val in attrs.iteritems():
s.write(' %s="%s"' % (key, escape_html(val)))
if close:
if body is None: s.write(' />')
else: s.write('>%s</%s>' % (body, tag))
else:
s.write('>')
return mark_safe(s.getvalue())
But now my HTML has escaped when I try to display it from my template. Everything else is exactly the same. It works correctly if you replace the last line with return mark_safe(unicode(s.getvalue())). I checked the return type s.getvalue(). It should be strlike the first function, so why doesn't it succeed?
Also, the failure SafeString(s.getvalue())fails SafeUnicode(s.getvalue()).
I would also like to point out that I used return mark_safe(s.getvalue())in another function without any odd behavior.
" " :
class Input(Widget):
def render(self):
return html_tag('input', attrs={'type':self.itype, 'id':self.id,
'name':self.name, 'value':self.value, 'class':self.itype})
class Field:
def __unicode__(self):
return mark_safe(self.widget.render())
{{myfield}} . , mark_safed 'd, , , , ... , , , , .