﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
8566	mark_safe not propagating from widgets to templates	agirman	nobody	"
I submitted the below to Django Users and Malcolm Tredinnick suggested I open a ticket.  Essentially, when making custom widgets, I encountered a problem wherein despite marking things as safe strings, when I tried to render my forms in a template, they were beings escaped.  Turning off auto escaping and piping to the safe filter weren't working, and I found that they were being escaped at a very low level.  Namely, there is a call in the Widget.render function to django.forms.util.flatatt that is escaping everything.  I don't know if this by design or not, but given the number of calls to mark_safe in the Widget module, I suspect not.  It is preventing me from, for example, making JS function calls in widgets that require string arguments.  I hope this helps.

Regards,

Alex.

====

Hi there,

I have been trying to get a function call into a widget argument, but
have not been able to at the template level, because it would appear
that my safe_strings are being escaped somewhere down in the
framework.  I have created a widget and mark_safe'd an attribute
value, but no matter what, since it's pre-escaped by the time it
bubbles up to the template level, I can't not escape it (well... I
could use an html library to de-escape it, but that seems kludgy).

I've traced the execution and found the culprit to be the
django.forms.util.flatatt function.  That is:

{{{
from django import forms
from django.utils.safestring import mark_safe

class MyWidget(forms.TextInput):
    def __init__(self, *args, **kwargs):
        attrs = kwargs.setdefault('attrs', {})
        attrs['safe_string'] = mark_safe(""will o' the wisp"")
        attrs['normal_string'] = ""cat o' nine tails""
        super(MyWidget, self).__init__(*args, **kwargs)

w = MyWidget()
w.render(""field_name"", """")

#=> u'<input normal_string=""cat o&#39; nine tails"" type=""text""
name=""field_name"" safe_string=""will o&#39; the wisp"" />'

}}}

You can see that both the unsafe and safe strings were escaped.  I
don't know if this is intentional or not, but it prevents me from
making something like:

{{{
<input type=""text"" onBlur=""myFunction('string_arg')"">
}}}

because it is always escaping my single-quotes.  Is this the desired
behavior?  Anyway, like I said, the culprit is:

{{{

# django.forms.util

def flatatt(attrs):

""""""
    Convert a dictionary of attributes to a single
string.
    The returned string will contain a leading space followed by
key=""value"",
    XML-style pairs.  It is assumed that the keys do not need to be
XML-
escaped.
    If the passed dictionary is empty, then return an empty
string.
    """"""
    return u''.join([u' %s=""%s""' % (k, escape(v)) for k, v in
attrs.items()])  # <-- right there, the escape(v) call... should this
be conditional_escape?

}}}

Since there are a lot of calls to mark_safe scattered through the
widget and form-level calls used in rendering, I assume you're meant
to be able to mark something as safe down here and have it get to the
top level unaltered...  no?

"		closed	Core (Other)	dev		fixed	mark_safe, safe string, escape, escaping, widgets		Unreviewed	0	0	0	0	0	0
