#8566 closed (fixed)
mark_safe not propagating from widgets to templates
Reported by: | agirman | Owned by: | nobody |
---|---|---|---|
Component: | Core (Other) | Version: | dev |
Severity: | Keywords: | mark_safe, safe string, escape, escaping, widgets | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
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' nine tails" type="text" name="field_name" safe_string="will o' 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?
Change History (6)
comment:1 by , 16 years ago
comment:3 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
follow-up: 5 comment:4 by , 15 years ago
milestone: | 1.0 → 1.2 |
---|---|
Resolution: | fixed |
Status: | closed → reopened |
It only propagates unicode safe strings (SafeUnicode), not simple strings (SafeString)
comment:5 by , 15 years ago
milestone: | 1.2 → 1.0 |
---|---|
Resolution: | → fixed |
Status: | reopened → closed |
Replying to Denis_Cheremisov:
It only propagates unicode safe strings (SafeUnicode), not simple strings (SafeString)
What is "It"? The committed changeset for this ticket didn't do anything with Safe[Anything], it simply added a call to conditional_escape. conditional_escape, from a quick check, checks for SafeData, the base for both SafeUnicdoe and SafeString. So it isn't at all clear to me what you are trying to report. As the fix for this bug was checked in nearly a year ago, without any immediate reaction that it was broken, it would be best at this point to open a new ticket describing in detail whatever problem you are encountering.
Alright, I should have previewed. Here is the code in a code block: