Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

newforms-admin: Merged trunk revision [6671].

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6776 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit f88babafc58eafece72d3f2f7444336c69196808 1 parent c82b2be
Joseph Kocherhans authored November 30, 2007

Showing 50 changed files with 1,184 additions and 310 deletions. Show diff stats Hide diff stats

  1. 6  django/contrib/admin/filterspecs.py
  2. 3  django/contrib/admin/models.py
  3. 5  django/contrib/admin/options.py
  4. 3  django/contrib/admin/sites.py
  5. 2  django/contrib/admin/templates/admin/base_site.html
  6. 4  django/contrib/admin/templates/admin/change_form.html
  7. 4  django/contrib/admin/templates/admin/date_hierarchy.html
  8. 4  django/contrib/admin/templates/admin/delete_confirmation.html
  9. 6  django/contrib/admin/templates/admin/index.html
  10. 2  django/contrib/admin/templates/admin/invalid_setup.html
  11. 6  django/contrib/admin/templates/admin/object_history.html
  12. 2  django/contrib/admin/templates/admin/pagination.html
  13. 8  django/contrib/admin/templates/admin_doc/model_detail.html
  14. 17  django/contrib/admin/templatetags/admin_list.py
  15. 19  django/contrib/admin/util.py
  16. 3  django/contrib/admin/views/decorators.py
  17. 2  django/contrib/admin/views/main.py
  18. 3  django/contrib/admindocs/utils.py
  19. 3  django/contrib/admindocs/views.py
  20. 7  django/contrib/csrf/middleware.py
  21. 13  django/contrib/databrowse/datastructures.py
  22. 12  django/contrib/databrowse/plugins/calendars.py
  23. 10  django/contrib/databrowse/plugins/fieldchoices.py
  24. 3  django/contrib/databrowse/sites.py
  25. 8  django/contrib/flatpages/views.py
  26. 4  django/contrib/humanize/templatetags/humanize.py
  27. 10  django/contrib/markup/templatetags/markup.py
  28. 6  django/contrib/markup/tests.py
  29. 3  django/contrib/sitemaps/templates/sitemap.xml
  30. 3  django/contrib/sitemaps/templates/sitemap_index.xml
  31. 15  django/newforms/forms.py
  32. 8  django/newforms/util.py
  33. 40  django/newforms/widgets.py
  34. 43  django/oldforms/__init__.py
  35. 70  django/template/__init__.py
  36. 5  django/template/context.py
  37. 173  django/template/defaultfilters.py
  38. 37  django/template/defaulttags.py
  39. 6  django/utils/encoding.py
  40. 33  django/utils/html.py
  41. 124  django/utils/safestring.py
  42. 30  django/views/debug.py
  43. 149  docs/templates.txt
  44. 142  docs/templates_python.txt
  45. 4  tests/regressiontests/defaultfilters/tests.py
  46. 2  tests/regressiontests/forms/forms.py
  47. 2  tests/regressiontests/forms/tests.py
  48. 3  tests/regressiontests/humanize/tests.py
  49. 220  tests/regressiontests/templates/filters.py
  50. 207  tests/regressiontests/templates/tests.py
6  django/contrib/admin/filterspecs.py
@@ -9,6 +9,8 @@
9 9
 from django.db import models
10 10
 from django.utils.encoding import smart_unicode, iri_to_uri
11 11
 from django.utils.translation import ugettext as _
  12
+from django.utils.html import escape
  13
+from django.utils.safestring import mark_safe
12 14
 import datetime
13 15
 
14 16
 class FilterSpec(object):
@@ -39,7 +41,7 @@ def title(self):
39 41
     def output(self, cl):
40 42
         t = []
41 43
         if self.has_output():
42  
-            t.append(_(u'<h3>By %s:</h3>\n<ul>\n') % self.title())
  44
+            t.append(_(u'<h3>By %s:</h3>\n<ul>\n') % escape(self.title()))
43 45
 
44 46
             for choice in self.choices(cl):
45 47
                 t.append(u'<li%s><a href="%s">%s</a></li>\n' % \
@@ -47,7 +49,7 @@ def output(self, cl):
47 49
                      iri_to_uri(choice['query_string']),
48 50
                      choice['display']))
49 51
             t.append('</ul>\n\n')
50  
-        return "".join(t)
  52
+        return mark_safe("".join(t))
51 53
 
52 54
 class RelatedFilterSpec(FilterSpec):
53 55
     def __init__(self, f, request, params, model, model_admin):
3  django/contrib/admin/models.py
@@ -3,6 +3,7 @@
3 3
 from django.contrib.auth.models import User
4 4
 from django.utils.translation import ugettext_lazy as _
5 5
 from django.utils.encoding import smart_unicode
  6
+from django.utils.safestring import mark_safe
6 7
 
7 8
 ADDITION = 1
8 9
 CHANGE = 2
@@ -49,4 +50,4 @@ def get_admin_url(self):
49 50
         Returns the admin URL to edit the object represented by this log entry.
50 51
         This is relative to the Django admin index page.
51 52
         """
52  
-        return u"%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, self.object_id)
  53
+        return mark_safe(u"%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, self.object_id))
5  django/contrib/admin/options.py
@@ -9,6 +9,7 @@
9 9
 from django.http import Http404, HttpResponse, HttpResponseRedirect
10 10
 from django.shortcuts import get_object_or_404, render_to_response
11 11
 from django.utils.html import escape
  12
+from django.utils.safestring import mark_safe
12 13
 from django.utils.text import capfirst, get_text_list
13 14
 from django.utils.translation import ugettext as _
14 15
 from django.utils.encoding import force_unicode
@@ -462,7 +463,7 @@ def render_change_form(self, model, context, add=False, change=False, form_url='
462 463
             'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
463 464
             'has_absolute_url': hasattr(model, 'get_absolute_url'),
464 465
             'ordered_objects': ordered_objects,
465  
-            'form_url': form_url,
  466
+            'form_url': mark_safe(form_url),
466 467
             'opts': opts,
467 468
             'content_type_id': ContentType.objects.get_for_model(model).id,
468 469
             'save_on_top': self.save_on_top,
@@ -652,7 +653,7 @@ def delete_view(self, request, object_id):
652 653
 
653 654
         # Populate deleted_objects, a data structure of all related objects that
654 655
         # will also be deleted.
655  
-        deleted_objects = [u'%s: <a href="../../%s/">%s</a>' % (force_unicode(capfirst(opts.verbose_name)), object_id, escape(str(obj))), []]
  656
+        deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), force_unicode(object_id), escape(obj))), []]
656 657
         perms_needed = sets.Set()
657 658
         get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1, self.admin_site)
658 659
 
3  django/contrib/admin/sites.py
@@ -3,6 +3,7 @@
3 3
 from django.contrib.auth import authenticate, login
4 4
 from django.db.models.base import ModelBase
5 5
 from django.shortcuts import render_to_response
  6
+from django.utils.safestring import mark_safe
6 7
 from django.utils.text import capfirst
7 8
 from django.utils.translation import ugettext_lazy, ugettext as _
8 9
 import base64
@@ -272,7 +273,7 @@ def index(self, request):
272 273
                 if True in perms.values():
273 274
                     model_dict = {
274 275
                         'name': capfirst(model._meta.verbose_name_plural),
275  
-                        'admin_url': '%s/%s/' % (app_label, model.__name__.lower()),
  276
+                        'admin_url': mark_safe('%s/%s/' % (app_label, model.__name__.lower())),
276 277
                         'perms': perms,
277 278
                     }
278 279
                     if app_label in app_dict:
2  django/contrib/admin/templates/admin/base_site.html
... ...
@@ -1,7 +1,7 @@
1 1
 {% extends "admin/base.html" %}
2 2
 {% load i18n %}
3 3
 
4  
-{% block title %}{{ title|escape }} | {% trans 'Django site admin' %}{% endblock %}
  4
+{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
5 5
 
6 6
 {% block branding %}
7 7
 <h1 id="site-name">{% trans 'Django administration' %}</h1>
4  django/contrib/admin/templates/admin/change_form.html
@@ -17,8 +17,8 @@
17 17
 {% block breadcrumbs %}{% if not is_popup %}
18 18
 <div class="breadcrumbs">
19 19
      <a href="../../../">{% trans "Home" %}</a> &rsaquo;
20  
-     <a href="../">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
21  
-     {% if add %}{% trans "Add" %} {{ opts.verbose_name|escape }}{% else %}{{ original|truncatewords:"18"|escape }}{% endif %}
  20
+     <a href="../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
  21
+     {% if add %}{% trans "Add" %} {{ opts.verbose_name }}{% else %}{{ original|truncatewords:"18" }}{% endif %}
22 22
 </div>
23 23
 {% endif %}{% endblock %}
24 24
 
4  django/contrib/admin/templates/admin/date_hierarchy.html
... ...
@@ -1,9 +1,9 @@
1 1
 {% if show %}
2 2
 <div class="xfull">
3 3
 <ul class="toplinks">
4  
-{% if back %}<li class="date-back"><a href="{{ back.link }}">&lsaquo; {{ back.title|escape }}</a></li>{% endif %}
  4
+{% if back %}<li class="date-back"><a href="{{ back.link }}">&lsaquo; {{ back.title }}</a></li>{% endif %}
5 5
 {% for choice in choices %}
6  
-<li> {% if choice.link %}<a href="{{ choice.link }}">{% endif %}{{ choice.title|escape }}{% if choice.link %}</a>{% endif %}</li>
  6
+<li> {% if choice.link %}<a href="{{ choice.link }}">{% endif %}{{ choice.title }}{% if choice.link %}</a>{% endif %}</li>
7 7
 {% endfor %}
8 8
 </ul><br class="clear" />
9 9
 </div>
4  django/contrib/admin/templates/admin/delete_confirmation.html
@@ -6,7 +6,7 @@
6 6
 {% block breadcrumbs %}
7 7
 <div class="breadcrumbs">
8 8
      <a href="../../../../">{% trans "Home" %}</a> &rsaquo;
9  
-     <a href="../../">{{ opts.verbose_name_plural|capfirst|escape }}</a> &rsaquo;
  9
+     <a href="../../">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
10 10
      <a href="../">{{ object|escape|truncatewords:"18" }}</a> &rsaquo;
11 11
      {% trans 'Delete' %}
12 12
 </div>
@@ -17,7 +17,7 @@
17 17
     <p>{% blocktrans with object|escape as escaped_object %}Deleting the {{ object_name }} '{{ escaped_object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
18 18
     <ul>
19 19
     {% for obj in perms_lacking %}
20  
-        <li>{{ obj|escape }}</li>
  20
+        <li>{{ obj }}</li>
21 21
     {% endfor %}
22 22
     </ul>
23 23
 {% else %}
6  django/contrib/admin/templates/admin/index.html
@@ -20,9 +20,9 @@
20 20
         {% for model in app.models %}
21 21
             <tr>
22 22
             {% if model.perms.change %}
23  
-                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name|escape }}</a></th>
  23
+                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
24 24
             {% else %}
25  
-                <th scope="row">{{ model.name|escape }}</th>
  25
+                <th scope="row">{{ model.name }}</th>
26 26
             {% endif %}
27 27
 
28 28
             {% if model.perms.add %}
@@ -59,7 +59,7 @@
59 59
             {% else %}
60 60
             <ul class="actionlist">
61 61
             {% for entry in admin_log %}
62  
-            <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr|escape }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{% filter capfirst|escape %}{% trans entry.content_type.name %}{% endfilter %}</span></li>
  62
+            <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">{% if not entry.is_deletion %}<a href="{{ entry.get_admin_url }}">{% endif %}{{ entry.object_repr|escape }}{% if not entry.is_deletion %}</a>{% endif %}<br /><span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}</span></li>
63 63
             {% endfor %}
64 64
             </ul>
65 65
             {% endif %}
2  django/contrib/admin/templates/admin/invalid_setup.html
... ...
@@ -1,7 +1,7 @@
1 1
 {% extends "admin/base_site.html" %}
2 2
 {% load i18n %}
3 3
 
4  
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {{ title|escape }}</div>{% endblock %}
  4
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {{ title }}</div>{% endblock %}
5 5
 
6 6
 {% block content %}
7 7
 <p>{% trans "Something's wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user." %}</p>
6  django/contrib/admin/templates/admin/object_history.html
@@ -4,7 +4,7 @@
4 4
 {% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
5 5
 
6 6
 {% block breadcrumbs %}
7  
-<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> &rsaquo; <a href="../../">{{ module_name|escape }}</a> &rsaquo; <a href="../">{{ object|escape|truncatewords:"18" }}</a> &rsaquo; {% trans 'History' %}</div>
  7
+<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> &rsaquo; <a href="../../">{{ module_name }}</a> &rsaquo; <a href="../">{{ object|truncatewords:"18" }}</a> &rsaquo; {% trans 'History' %}</div>
8 8
 {% endblock %}
9 9
 
10 10
 {% block content %}
@@ -24,8 +24,8 @@
24 24
         {% for action in action_list %}
25 25
         <tr>
26 26
             <th scope="row">{{ action.action_time|date:_("DATE_WITH_TIME_FULL") }}</th>
27  
-            <td>{{ action.user.username }}{% if action.user.first_name %} ({{ action.user.first_name|escape }} {{ action.user.last_name|escape }}){% endif %}</td>
28  
-            <td>{{ action.change_message|escape }}</td>
  27
+            <td>{{ action.user.username }}{% if action.user.first_name %} ({{ action.user.first_name }} {{ action.user.last_name }}){% endif %}</td>
  28
+            <td>{{ action.change_message }}</td>
29 29
         </tr>
30 30
         {% endfor %}
31 31
         </tbody>
2  django/contrib/admin/templates/admin/pagination.html
@@ -6,6 +6,6 @@
6 6
     {% paginator_number cl i %}
7 7
 {% endfor %}
8 8
 {% endif %}
9  
-{{ cl.result_count }} {% ifequal cl.result_count 1 %}{{ cl.opts.verbose_name|escape }}{% else %}{{ cl.opts.verbose_name_plural|escape }}{% endifequal %}
  9
+{{ cl.result_count }} {% ifequal cl.result_count 1 %}{{ cl.opts.verbose_name|escape }}{% else %}{{ cl.opts.verbose_name_plural }}{% endifequal %}
10 10
 {% if show_all_url %}&nbsp;&nbsp;<a href="{{ show_all_url }}" class="showall">{% trans 'Show all' %}</a>{% endif %}
11 11
 </p>
8  django/contrib/admin/templates/admin_doc/model_detail.html
@@ -9,16 +9,16 @@
9 9
 </style>
10 10
 {% endblock %}
11 11
 
12  
-{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Models</a> &rsaquo; {{ name|escape }}</div>{% endblock %}
  12
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> &rsaquo; <a href="../../">Documentation</a> &rsaquo; <a href="../">Models</a> &rsaquo; {{ name }}</div>{% endblock %}
13 13
 
14  
-{% block title %}Model: {{ name|escape }}{% endblock %}
  14
+{% block title %}Model: {{ name }}{% endblock %}
15 15
 
16 16
 {% block content %}
17 17
 <div id="content-main">
18  
-<h1>{{ summary|escape }}</h1>
  18
+<h1>{{ summary }}</h1>
19 19
 
20 20
 {% if description %}
21  
-  <p>{% filter escape|linebreaksbr %}{% trans description %}{% endfilter %}</p>
  21
+  <p>{% filter linebreaksbr %}{% trans description %}{% endfilter %}</p>
22 22
 {% endif %}
23 23
 
24 24
 <div class="module">
17  django/contrib/admin/templatetags/admin_list.py
@@ -4,8 +4,9 @@
4 4
 from django.core.exceptions import ObjectDoesNotExist
5 5
 from django.db import models
6 6
 from django.utils import dateformat
7  
-from django.utils.html import escape
  7
+from django.utils.html import escape, conditional_escape
8 8
 from django.utils.text import capfirst
  9
+from django.utils.safestring import mark_safe
9 10
 from django.utils.translation import get_date_formats, get_partial_date_formats, ugettext as _
10 11
 from django.utils.encoding import smart_unicode, smart_str, force_unicode
11 12
 from django.template import Library
@@ -19,9 +20,9 @@ def paginator_number(cl,i):
19 20
     if i == DOT:
20 21
         return u'... '
21 22
     elif i == cl.page_num:
22  
-        return u'<span class="this-page">%d</span> ' % (i+1)
  23
+        return mark_safe(u'<span class="this-page">%d</span> ' % (i+1))
23 24
     else:
24  
-        return u'<a href="%s"%s>%d</a> ' % (cl.get_query_string({PAGE_VAR: i}), (i == cl.paginator.pages-1 and ' class="end"' or ''), i+1)
  25
+        return mark_safe(u'<a href="%s"%s>%d</a> ' % (cl.get_query_string({PAGE_VAR: i}), (i == cl.paginator.pages-1 and ' class="end"' or ''), i+1))
25 26
 paginator_number = register.simple_tag(paginator_number)
26 27
 
27 28
 def pagination(cl):
@@ -117,7 +118,7 @@ def result_headers(cl):
117 118
 
118 119
 def _boolean_icon(field_val):
119 120
     BOOLEAN_MAPPING = {True: 'yes', False: 'no', None: 'unknown'}
120  
-    return u'<img src="%simg/admin/icon-%s.gif" alt="%s" />' % (settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val)
  121
+    return mark_safe(u'<img src="%simg/admin/icon-%s.gif" alt="%s" />' % (settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val))
121 122
 
122 123
 def items_for_result(cl, result):
123 124
     first = True
@@ -193,10 +194,10 @@ def items_for_result(cl, result):
193 194
             # Convert the pk to something that can be used in Javascript.
194 195
             # Problem cases are long ints (23L) and non-ASCII strings.
195 196
             result_id = repr(force_unicode(getattr(result, pk)))[1:]
196  
-            yield (u'<%s%s><a href="%s"%s>%s</a></%s>' % \
197  
-                (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), result_repr, table_tag))
  197
+            yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \
  198
+                (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
198 199
         else:
199  
-            yield (u'<td%s>%s</td>' % (row_class, result_repr))
  200
+            yield mark_safe(u'<td%s>%s</td>' % (row_class, conditional_escape(result_repr)))
200 201
 
201 202
 def results(cl):
202 203
     for res in cl.result_list:
@@ -220,7 +221,7 @@ def date_hierarchy(cl):
220 221
         day_lookup = cl.params.get(day_field)
221 222
         year_month_format, month_day_format = get_partial_date_formats()
222 223
 
223  
-        link = lambda d: cl.get_query_string(d, [field_generic])
  224
+        link = lambda d: mark_safe(cl.get_query_string(d, [field_generic]))
224 225
 
225 226
         if year_lookup and month_lookup and day_lookup:
226 227
             day = datetime.date(int(year_lookup), int(month_lookup), int(day_lookup))
19  django/contrib/admin/util.py
... ...
@@ -1,6 +1,7 @@
1 1
 from django.core.exceptions import ObjectDoesNotExist
2 2
 from django.db import models
3 3
 from django.utils.html import escape
  4
+from django.utils.safestring import mark_safe
4 5
 from django.utils.text import capfirst
5 6
 from django.utils.encoding import force_unicode
6 7
 
@@ -37,12 +38,14 @@ def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_
37 38
                 if related.field.rel.edit_inline or not has_admin:
38 39
                     # Don't display link to edit, because it either has no
39 40
                     # admin or is edited inline.
40  
-                    nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
  41
+                    nh(deleted_objects, current_depth, [mark_safe(u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj)), []])
41 42
                 else:
42 43
                     # Display a link to the admin page.
43  
-                    nh(deleted_objects, current_depth, [u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
44  
-                        (force_unicode(capfirst(related.opts.verbose_name)), related.opts.app_label, related.opts.object_name.lower(),
45  
-                        sub_obj._get_pk_val(), sub_obj), []])
  44
+                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="../../../../%s/%s/%s/">%s</a>' %
  45
+                        (escape(force_unicode(capfirst(related.opts.verbose_name))),
  46
+                            related.opts.app_label,
  47
+                            related.opts.object_name.lower(),
  48
+                            sub_obj._get_pk_val(), sub_obj)), []])
46 49
                 get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2, admin_site)
47 50
         else:
48 51
             has_related_objs = False
@@ -54,8 +57,8 @@ def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_
54 57
                     nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), escape(sub_obj)), []])
55 58
                 else:
56 59
                     # Display a link to the admin page.
57  
-                    nh(deleted_objects, current_depth, [u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
58  
-                        (force_unicode(capfirst(related.opts.verbose_name)), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(sub_obj)), []])
  60
+                    nh(deleted_objects, current_depth, [mark_safe(u'%s: <a href="../../../../%s/%s/%s/">%s</a>' % \
  61
+                        (escape(force_unicode(capfirst(related.opts.verbose_name))), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(sub_obj))), []])
59 62
                 get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2, admin_site)
60 63
             # If there were related objects, and the user doesn't have
61 64
             # permission to delete them, add the missing perm to perms_needed.
@@ -87,9 +90,9 @@ def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_
87 90
                 else:
88 91
                     # Display a link to the admin page.
89 92
                     nh(deleted_objects, current_depth, [
90  
-                        (_('One or more %(fieldname)s in %(name)s:') % {'fieldname': force_unicode(related.field.verbose_name), 'name': force_unicode(related.opts.verbose_name)}) + \
  93
+                        mark_safe((_('One or more %(fieldname)s in %(name)s:') % {'fieldname': escape(force_unicode(related.field.verbose_name)), 'name': escape(force_unicode(related.opts.verbose_name))}) + \
91 94
                         (u' <a href="../../../../%s/%s/%s/">%s</a>' % \
92  
-                            (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(sub_obj))), []])
  95
+                            (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(sub_obj)))), []])
93 96
         # If there were related objects, and the user doesn't have
94 97
         # permission to change them, add the missing perm to perms_needed.
95 98
         if has_admin and has_related_objs:
3  django/contrib/admin/views/decorators.py
@@ -4,6 +4,7 @@
4 4
 from django.contrib.auth import authenticate, login
5 5
 from django.shortcuts import render_to_response
6 6
 from django.utils.translation import ugettext_lazy, ugettext as _
  7
+from django.utils.safestring import mark_safe
7 8
 import base64, datetime, md5
8 9
 import cPickle as pickle
9 10
 
@@ -22,7 +23,7 @@ def _display_login_form(request, error_message=''):
22 23
         post_data = _encode_post_data({})
23 24
     return render_to_response('admin/login.html', {
24 25
         'title': _('Log in'),
25  
-        'app_path': request.path,
  26
+        'app_path': mark_safe(request.path),
26 27
         'post_data': post_data,
27 28
         'error_message': error_message
28 29
     }, context_instance=template.RequestContext(request))
2  django/contrib/admin/views/main.py
@@ -173,7 +173,7 @@ def get_query_string(self, new_params=None, remove=None):
173 173
                 del p[k]
174 174
             elif v is not None:
175 175
                 p[k] = v
176  
-        return '?' + '&amp;'.join([u'%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20')
  176
+        return mark_safe('?' + '&amp;'.join([u'%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20'))
177 177
 
178 178
     def get_results(self, request):
179 179
         paginator = ObjectPaginator(self.query_set, self.list_per_page)
3  django/contrib/admindocs/utils.py
@@ -3,6 +3,7 @@
3 3
 import re
4 4
 from email.Parser import HeaderParser
5 5
 from email.Errors import HeaderParseError
  6
+from django.utils.safestring import mark_safe
6 7
 try:
7 8
     import docutils.core
8 9
     import docutils.nodes
@@ -66,7 +67,7 @@ def parse_rst(text, default_reference_context, thing_being_parsed=None, link_bas
66 67
     parts = docutils.core.publish_parts(text, source_path=thing_being_parsed,
67 68
                 destination_path=None, writer_name='html',
68 69
                 settings_overrides=overrides)
69  
-    return parts['fragment']
  70
+    return mark_safe(parts['fragment'])
70 71
 
71 72
 #
72 73
 # reST roles
3  django/contrib/admindocs/views.py
@@ -10,6 +10,7 @@
10 10
 from django.contrib.admindocs import utils
11 11
 from django.contrib.sites.models import Site
12 12
 from django.utils.translation import ugettext as _
  13
+from django.utils.safestring import mark_safe
13 14
 import inspect, os, re
14 15
 
15 16
 # Exclude methods starting with these strings from documentation
@@ -29,7 +30,7 @@ def bookmarklets(request):
29 30
     # Hack! This couples this view to the URL it lives at.
30 31
     admin_root = request.path[:-len('doc/bookmarklets/')]
31 32
     return render_to_response('admin_doc/bookmarklets.html', {
32  
-        'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', get_host(request), admin_root),
  33
+        'admin_url': mark_safe("%s://%s%s" % (request.is_secure() and 'https' or 'http', request.get_host(), admin_root)),
33 34
     }, context_instance=RequestContext(request))
34 35
 bookmarklets = staff_member_required(bookmarklets)
35 36
 
7  django/contrib/csrf/middleware.py
@@ -7,11 +7,12 @@
7 7
 """
8 8
 from django.conf import settings
9 9
 from django.http import HttpResponseForbidden
  10
+from django.utils.safestring import mark_safe
10 11
 import md5
11 12
 import re
12 13
 import itertools
13 14
 
14  
-_ERROR_MSG = '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>'
  15
+_ERROR_MSG = mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>')
15 16
 
16 17
 _POST_FORM_RE = \
17 18
     re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
@@ -82,10 +83,10 @@ def process_response(self, request, response):
82 83
                                             itertools.repeat(''))
83 84
             def add_csrf_field(match):
84 85
                 """Returns the matched <form> tag plus the added <input> element"""
85  
-                return match.group() + "<div style='display:none;'>" + \
  86
+                return mark_safe(match.group() + "<div style='display:none;'>" + \
86 87
                 "<input type='hidden' " + idattributes.next() + \
87 88
                 " name='csrfmiddlewaretoken' value='" + csrf_token + \
88  
-                "' /></div>"
  89
+                "' /></div>")
89 90
 
90 91
             # Modify any POST forms
91 92
             response.content = _POST_FORM_RE.sub(add_csrf_field, response.content)
13  django/contrib/databrowse/datastructures.py
@@ -8,6 +8,7 @@
8 8
 from django.utils.text import capfirst
9 9
 from django.utils.translation import get_date_formats
10 10
 from django.utils.encoding import smart_unicode, smart_str, iri_to_uri
  11
+from django.utils.safestring import mark_safe
11 12
 from django.db.models.query import QuerySet
12 13
 
13 14
 EMPTY_VALUE = '(None)'
@@ -28,7 +29,7 @@ def model_databrowse(self):
28 29
         return self.site.registry[self.model]
29 30
 
30 31
     def url(self):
31  
-        return '%s%s/%s/' % (self.site.root_url, self.model._meta.app_label, self.model._meta.module_name)
  32
+        return mark_safe('%s%s/%s/' % (self.site.root_url, self.model._meta.app_label, self.model._meta.module_name))
32 33
 
33 34
     def objects(self, **kwargs):
34 35
         return self.get_query_set().filter(**kwargs)
@@ -68,9 +69,9 @@ def choices(self):
68 69
 
69 70
     def url(self):
70 71
         if self.field.choices:
71  
-            return '%s%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name)
  72
+            return mark_safe('%s%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name))
72 73
         elif self.field.rel:
73  
-            return '%s%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name)
  74
+            return mark_safe('%s%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name))
74 75
 
75 76
 class EasyChoice(object):
76 77
     def __init__(self, easy_model, field, value, label):
@@ -81,7 +82,7 @@ def __repr__(self):
81 82
         return smart_str(u'<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name))
82 83
 
83 84
     def url(self):
84  
-        return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value))
  85
+        return mark_safe('%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value)))
85 86
 
86 87
 class EasyInstance(object):
87 88
     def __init__(self, easy_model, instance):
@@ -184,14 +185,14 @@ def urls(self):
184 185
             if self.field.rel.to in self.model.model_list:
185 186
                 lst = []
186 187
                 for value in self.values():
187  
-                    url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val()))
  188
+                    url = mark_safe('%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val())))
188 189
                     lst.append((smart_unicode(value), url))
189 190
             else:
190 191
                 lst = [(value, None) for value in self.values()]
191 192
         elif self.field.choices:
192 193
             lst = []
193 194
             for value in self.values():
194  
-                url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value))
  195
+                url = mark_safe('%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value)))
195 196
                 lst.append((value, url))
196 197
         elif isinstance(self.field, models.URLField):
197 198
             val = self.values()[0]
12  django/contrib/databrowse/plugins/calendars.py
@@ -5,8 +5,9 @@
5 5
 from django.shortcuts import render_to_response
6 6
 from django.utils.text import capfirst
7 7
 from django.utils.translation import get_date_formats
8  
-from django.views.generic import date_based
9 8
 from django.utils.encoding import force_unicode
  9
+from django.utils.safestring import mark_safe
  10
+from django.views.generic import date_based
10 11
 import datetime
11 12
 import time
12 13
 
@@ -29,16 +30,17 @@ def model_index_html(self, request, model, site):
29 30
         fields = self.field_dict(model)
30 31
         if not fields:
31 32
             return u''
32  
-        return u'<p class="filter"><strong>View calendar by:</strong> %s</p>' % \
33  
-            u', '.join(['<a href="calendars/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()])
  33
+        return mark_safe(u'<p class="filter"><strong>View calendar by:</strong> %s</p>' % \
  34
+            u', '.join(['<a href="calendars/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()]))
34 35
 
35 36
     def urls(self, plugin_name, easy_instance_field):
36 37
         if isinstance(easy_instance_field.field, models.DateField):
37  
-            return [u'%s%s/%s/%s/%s/%s/' % (easy_instance_field.model.url(),
  38
+            return [mark_safe(u'%s%s/%s/%s/%s/%s/' % (
  39
+                easy_instance_field.model.url(),
38 40
                 plugin_name, easy_instance_field.field.name,
39 41
                 easy_instance_field.raw_value.year,
40 42
                 easy_instance_field.raw_value.strftime('%b').lower(),
41  
-                easy_instance_field.raw_value.day)]
  43
+                easy_instance_field.raw_value.day))]
42 44
 
43 45
     def model_view(self, request, model_databrowse, url):
44 46
         self.model, self.site = model_databrowse.model, model_databrowse.site
10  django/contrib/databrowse/plugins/fieldchoices.py
@@ -5,6 +5,7 @@
5 5
 from django.shortcuts import render_to_response
6 6
 from django.utils.text import capfirst
7 7
 from django.utils.encoding import smart_str, force_unicode
  8
+from django.utils.safestring import mark_safe
8 9
 from django.views.generic import date_based
9 10
 import datetime
10 11
 import time
@@ -32,15 +33,16 @@ def model_index_html(self, request, model, site):
32 33
         fields = self.field_dict(model)
33 34
         if not fields:
34 35
             return u''
35  
-        return u'<p class="filter"><strong>View by:</strong> %s</p>' % \
36  
-            u', '.join(['<a href="fields/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()])
  36
+        return mark_safe(u'<p class="filter"><strong>View by:</strong> %s</p>' % \
  37
+            u', '.join(['<a href="fields/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()]))
37 38
 
38 39
     def urls(self, plugin_name, easy_instance_field):
39 40
         if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values():
40 41
             field_value = smart_str(easy_instance_field.raw_value)
41  
-            return [u'%s%s/%s/%s/' % (easy_instance_field.model.url(),
  42
+            return [mark_safe(u'%s%s/%s/%s/' % (
  43
+                easy_instance_field.model.url(),
42 44
                 plugin_name, easy_instance_field.field.name,
43  
-                urllib.quote(field_value, safe=''))]
  45
+                urllib.quote(field_value, safe='')))]
44 46
 
45 47
     def model_view(self, request, model_databrowse, url):
46 48
         self.model, self.site = model_databrowse.model, model_databrowse.site
3  django/contrib/databrowse/sites.py
@@ -2,6 +2,7 @@
2 2
 from django.db import models
3 3
 from django.contrib.databrowse.datastructures import EasyModel, EasyChoice
4 4
 from django.shortcuts import render_to_response
  5
+from django.utils.safestring import mark_safe
5 6
 
6 7
 class AlreadyRegistered(Exception):
7 8
     pass
@@ -60,7 +61,7 @@ def root(self, request, url):
60 61
 
61 62
     def main_view(self, request):
62 63
         easy_model = EasyModel(self.site, self.model)
63  
-        html_snippets = u'\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()])
  64
+        html_snippets = mark_safe(u'\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()]))
64 65
         return render_to_response('databrowse/model_detail.html', {
65 66
             'model': easy_model,
66 67
             'root_url': self.site.root_url,
8  django/contrib/flatpages/views.py
@@ -4,6 +4,7 @@
4 4
 from django.http import HttpResponse
5 5
 from django.conf import settings
6 6
 from django.core.xheaders import populate_xheaders
  7
+from django.utils.safestring import mark_safe
7 8
 
8 9
 DEFAULT_TEMPLATE = 'flatpages/default.html'
9 10
 
@@ -30,6 +31,13 @@ def flatpage(request, url):
30 31
         t = loader.select_template((f.template_name, DEFAULT_TEMPLATE))
31 32
     else:
32 33
         t = loader.get_template(DEFAULT_TEMPLATE)
  34
+
  35
+    # To avoid having to always use the "|safe" filter in flatpage templates,
  36
+    # mark the title and content as already safe (since they are raw HTML
  37
+    # content in the first place).
  38
+    f.title = mark_safe(f.title)
  39
+    f.content = mark_safe(f.content)
  40
+
33 41
     c = RequestContext(request, {
34 42
         'flatpage': f,
35 43
     })
4  django/contrib/humanize/templatetags/humanize.py
@@ -21,6 +21,7 @@ def ordinal(value):
21 21
     if value % 100 in (11, 12, 13): # special case
22 22
         return u"%d%s" % (value, t[0])
23 23
     return u'%d%s' % (value, t[value % 10])
  24
+ordinal.is_safe = True
24 25
 register.filter(ordinal)
25 26
 
26 27
 def intcomma(value):
@@ -34,6 +35,7 @@ def intcomma(value):
34 35
         return new
35 36
     else:
36 37
         return intcomma(new)
  38
+intcomma.is_safe = True
37 39
 register.filter(intcomma)
38 40
 
39 41
 def intword(value):
@@ -55,6 +57,7 @@ def intword(value):
55 57
         new_value = value / 1000000000000.0
56 58
         return ungettext('%(value).1f trillion', '%(value).1f trillion', new_value) % {'value': new_value}
57 59
     return value
  60
+intword.is_safe = False
58 61
 register.filter(intword)
59 62
 
60 63
 def apnumber(value):
@@ -69,6 +72,7 @@ def apnumber(value):
69 72
     if not 0 < value < 10:
70 73
         return value
71 74
     return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1]
  75
+apnumber.is_safe = True
72 76
 register.filter(apnumber)
73 77
 
74 78
 def naturalday(value, arg=None):
10  django/contrib/markup/templatetags/markup.py
@@ -17,6 +17,7 @@
17 17
 from django import template
18 18
 from django.conf import settings
19 19
 from django.utils.encoding import smart_str, force_unicode
  20
+from django.utils.safestring import mark_safe
20 21
 
21 22
 register = template.Library()
22 23
 
@@ -28,7 +29,8 @@ def textile(value):
28 29
             raise template.TemplateSyntaxError, "Error in {% textile %} filter: The Python textile library isn't installed."
29 30
         return force_unicode(value)
30 31
     else:
31  
-        return force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8'))
  32
+        return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8')))
  33
+textile.is_safe = True
32 34
 
33 35
 def markdown(value):
34 36
     try:
@@ -38,7 +40,8 @@ def markdown(value):
38 40
             raise template.TemplateSyntaxError, "Error in {% markdown %} filter: The Python markdown library isn't installed."
39 41
         return force_unicode(value)
40 42
     else:
41  
-        return force_unicode(markdown.markdown(smart_str(value)))
  43
+        return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
  44
+markdown.is_safe = True
42 45
 
43 46
 def restructuredtext(value):
44 47
     try:
@@ -50,7 +53,8 @@ def restructuredtext(value):
50 53
     else:
51 54
         docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
52 55
         parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings)
53  
-        return force_unicode(parts["fragment"])
  56
+        return mark_safe(force_unicode(parts["fragment"]))
  57
+restructuredtext.is_safe = True
54 58
 
55 59
 register.filter(textile)
56 60
 register.filter(markdown)
6  django/contrib/markup/tests.py
... ...
@@ -1,9 +1,11 @@
1 1
 # Quick tests for the markup templatetags (django.contrib.markup)
2 2
 
3  
-from django.template import Template, Context, add_to_builtins
4 3
 import re
5 4
 import unittest
6 5
 
  6
+from django.template import Template, Context, add_to_builtins
  7
+from django.utils.html import escape
  8
+
7 9
 add_to_builtins('django.contrib.markup.templatetags.markup')
8 10
 
9 11
 class Templates(unittest.TestCase):
@@ -24,7 +26,7 @@ def test_textile(self):
24 26
 
25 27
 <p>Paragraph 2 with &#8220;quotes&#8221; and <code>code</code></p>""")
26 28
         else:
27  
-            self.assertEqual(rendered, textile_content)
  29
+            self.assertEqual(rendered, escape(textile_content))
28 30
 
29 31
     def test_markdown(self):
30 32
         try:
3  django/contrib/sitemaps/templates/sitemap.xml
... ...
@@ -1,4 +1,4 @@
1  
-<?xml version="1.0" encoding="UTF-8"?>
  1
+{% autoescape off %}<?xml version="1.0" encoding="UTF-8"?>
2 2
 <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3 3
 {% spaceless %}
4 4
 {% for url in urlset %}
@@ -11,3 +11,4 @@
11 11
 {% endfor %}
12 12
 {% endspaceless %}
13 13
 </urlset>
  14
+{% endautoescape %}
3  django/contrib/sitemaps/templates/sitemap_index.xml
... ...
@@ -1,4 +1,5 @@
1  
-<?xml version="1.0" encoding="UTF-8"?>
  1
+{% autoescape off %}<?xml version="1.0" encoding="UTF-8"?>
2 2
 <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3 3
 {% for location in sitemaps %}<sitemap><loc>{{ location|escape }}</loc></sitemap>{% endfor %}
4 4
 </sitemapindex>
  5
+{% endautoescape %}
15  django/newforms/forms.py
@@ -7,6 +7,7 @@
7 7
 from django.utils.datastructures import SortedDict
8 8
 from django.utils.html import escape
9 9
 from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode
  10
+from django.utils.safestring import mark_safe
10 11
 
11 12
 from fields import Field
12 13
 from widgets import Media, media_property, TextInput, Textarea
@@ -123,7 +124,8 @@ def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_
123 124
                     output.append(error_row % force_unicode(bf_errors))
124 125
                 if bf.label:
125 126
                     label = escape(force_unicode(bf.label))
126  
-                    # Only add the suffix if the label does not end in punctuation.
  127
+                    # Only add the suffix if the label does not end in
  128
+                    # punctuation.
127 129
                     if self.label_suffix:
128 130
                         if label[-1] not in ':?.!':
129 131
                             label += self.label_suffix
@@ -141,11 +143,14 @@ def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_
141 143
             str_hidden = u''.join(hidden_fields)
142 144
             if output:
143 145
                 last_row = output[-1]
144  
-                # Chop off the trailing row_ender (e.g. '</td></tr>') and insert the hidden fields.
  146
+                # Chop off the trailing row_ender (e.g. '</td></tr>') and
  147
+                # insert the hidden fields.
145 148
                 output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender
146  
-            else: # If there aren't any rows in the output, just append the hidden fields.
  149
+            else:
  150
+                # If there aren't any rows in the output, just append the
  151
+                # hidden fields.
147 152
                 output.append(str_hidden)
148  
-        return u'\n'.join(output)
  153
+        return mark_safe(u'\n'.join(output))
149 154
 
150 155
     def as_table(self):
151 156
         "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
@@ -343,7 +348,7 @@ def label_tag(self, contents=None, attrs=None):
343 348
         if id_:
344 349
             attrs = attrs and flatatt(attrs) or ''
345 350
             contents = '<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, contents)
346  
-        return contents
  351
+        return mark_safe(contents)
347 352
 
348 353
     def _is_hidden(self):
349 354
         "Returns True if this BoundField's widget is hidden."
8  django/newforms/util.py
... ...
@@ -1,6 +1,7 @@
1 1
 from django.utils.html import escape
2 2
 from django.utils.encoding import smart_unicode, StrAndUnicode, force_unicode
3 3
 from django.utils.functional import Promise
  4
+from django.utils.safestring import mark_safe
4 5
 
5 6
 def flatatt(attrs):
6 7
     """
@@ -22,7 +23,9 @@ def __unicode__(self):
22 23
 
23 24
     def as_ul(self):
24 25
         if not self: return u''
25  
-        return u'<ul class="errorlist">%s</ul>' % ''.join([u'<li>%s%s</li>' % (k, force_unicode(v)) for k, v in self.items()])
  26
+        return mark_safe(u'<ul class="errorlist">%s</ul>'
  27
+                % ''.join([u'<li>%s%s</li>' % (k, force_unicode(v))
  28
+                    for k, v in self.items()]))
26 29
 
27 30
     def as_text(self):
28 31
         return u'\n'.join([u'* %s\n%s' % (k, u'\n'.join([u'  * %s' % force_unicode(i) for i in v])) for k, v in self.items()])
@@ -36,7 +39,8 @@ def __unicode__(self):
36 39
 
37 40
     def as_ul(self):
38 41
         if not self: return u''
39  
-        return u'<ul class="errorlist">%s</ul>' % ''.join([u'<li>%s</li>' % force_unicode(e) for e in self])
  42
+        return mark_safe(u'<ul class="errorlist">%s</ul>'
  43
+                % ''.join([u'<li>%s</li>' % force_unicode(e) for e in self]))
40 44
 
41 45
     def as_text(self):
42 46
         if not self: return u''
40  django/newforms/widgets.py
@@ -14,6 +14,7 @@
14 14
 from django.utils.html import escape
15 15
 from django.utils.translation import ugettext
16 16
 from django.utils.encoding import StrAndUnicode, force_unicode
  17
+from django.utils.safestring import mark_safe
17 18
 from util import flatatt
18 19
 from urlparse import urljoin
19 20
 
@@ -188,8 +189,10 @@ class Input(Widget):
188 189
     def render(self, name, value, attrs=None):
189 190
         if value is None: value = ''
190 191
         final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
191  
-        if value != '': final_attrs['value'] = force_unicode(value) # Only add the 'value' attribute if a value is non-empty.
192  
-        return u'<input%s />' % flatatt(final_attrs)
  192
+        if value != '':
  193
+            # Only add the 'value' attribute if a value is non-empty.
  194
+            final_attrs['value'] = force_unicode(value)
  195
+        return mark_safe(u'<input%s />' % flatatt(final_attrs))
193 196
 
194 197
 class TextInput(Input):
195 198
     input_type = 'text'
@@ -222,7 +225,9 @@ def __init__(self, attrs=None, choices=()):
222 225
     def render(self, name, value, attrs=None, choices=()):
223 226
         if value is None: value = []
224 227
         final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
225  
-        return u'\n'.join([(u'<input%s />' % flatatt(dict(value=force_unicode(v), **final_attrs))) for v in value])
  228
+        return mark_safe(u'\n'.join([(u'<input%s />' %
  229
+            flatatt(dict(value=force_unicode(v), **final_attrs)))
  230
+            for v in value]))
226 231
 
227 232
     def value_from_datadict(self, data, files, name):
228 233
         if isinstance(data, MultiValueDict):
@@ -251,7 +256,8 @@ def render(self, name, value, attrs=None):
251 256
         if value is None: value = ''
252 257
         value = force_unicode(value)
253 258
         final_attrs = self.build_attrs(attrs, name=name)
254  
-        return u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), escape(value))
  259
+        return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs),
  260
+                escape(value)))
255 261
 
256 262
 class DateTimeInput(Input):
257 263
     input_type = 'text'
@@ -285,8 +291,9 @@ def render(self, name, value, attrs=None):
285 291
         if result:
286 292
             final_attrs['checked'] = 'checked'
287 293
         if value not in ('', True, False, None):
288  
-            final_attrs['value'] = force_unicode(value) # Only add the 'value' attribute if a value is non-empty.
289  
-        return u'<input%s />' % flatatt(final_attrs)
  294
+            # Only add the 'value' attribute if a value is non-empty.
  295
+            final_attrs['value'] = force_unicode(value)
  296
+        return mark_safe(u'<input%s />' % flatatt(final_attrs))
290 297
 
291 298
     def value_from_datadict(self, data, files, name):
292 299
         if name not in data:
@@ -307,13 +314,14 @@ def render(self, name, value, attrs=None, choices=()):
307 314
         if value is None: value = ''
308 315
         final_attrs = self.build_attrs(attrs, name=name)
309 316
         output = [u'<select%s>' % flatatt(final_attrs)]
310  
-        str_value = force_unicode(value) # Normalize to string.
  317
+        # Normalize to string.
  318
+        str_value = force_unicode(value)
311 319
         for option_value, option_label in chain(self.choices, choices):
312 320
             option_value = force_unicode(option_value)
313 321
             selected_html = (option_value == str_value) and u' selected="selected"' or ''
314 322
             output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label))))
315 323
         output.append(u'</select>')
316  
-        return u'\n'.join(output)
  324
+        return mark_safe(u'\n'.join(output))
317 325
 
318 326
 class NullBooleanSelect(Select):
319 327
     """
@@ -350,7 +358,7 @@ def render(self, name, value, attrs=None, choices=()):
350 358
             selected_html = (option_value in str_values) and ' selected="selected"' or ''
351 359
             output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label))))
352 360
         output.append(u'</select>')
353  
-        return u'\n'.join(output)
  361
+        return mark_safe(u'\n'.join(output))
354 362
 
355 363
     def value_from_datadict(self, data, files, name):
356 364
         if isinstance(data, MultiValueDict):
@@ -371,7 +379,8 @@ def __init__(self, name, value, attrs, choice, index):
371 379
         self.index = index
372 380
 
373 381
     def __unicode__(self):
374  
-        return u'<label>%s %s</label>' % (self.tag(), self.choice_label)
  382
+        return mark_safe(u'<label>%s %s</label>' % (self.tag(),
  383
+                self.choice_label))
375 384
 
376 385
     def is_checked(self):
377 386
         return self.value == self.choice_value
@@ -382,7 +391,7 @@ def tag(self):
382 391
         final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value)
383 392
         if self.is_checked():
384 393
             final_attrs['checked'] = 'checked'
385  
-        return u'<input%s />' % flatatt(final_attrs)
  394
+        return mark_safe(u'<input%s />' % flatatt(final_attrs))
386 395
 
387 396
 class RadioFieldRenderer(StrAndUnicode):
388 397
     """
@@ -406,7 +415,8 @@ def __unicode__(self):
406 415
 
407 416
     def render(self):
408 417
         """Outputs a <ul> for this set of radio fields."""
409  
-        return u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % force_unicode(w) for w in self])
  418
+        return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>'
  419
+                % force_unicode(w) for w in self]))
410 420
 
411 421
 class RadioSelect(Select):
412 422
 
@@ -443,7 +453,8 @@ def render(self, name, value, attrs=None, choices=()):
443 453
         has_id = attrs and 'id' in attrs
444 454
         final_attrs = self.build_attrs(attrs, name=name)
445 455
         output = [u'<ul>']
446  
-        str_values = set([force_unicode(v) for v in value]) # Normalize to strings.
  456
+        # Normalize to strings
  457
+        str_values = set([force_unicode(v) for v in value])
447 458
         for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
448 459
             # If an ID attribute was given, add a numeric index as a suffix,
449 460
             # so that the checkboxes don't all have the same ID attribute.
@@ -454,7 +465,7 @@ def render(self, name, value, attrs=None, choices=()):
454 465
             rendered_cb = cb.render(name, option_value)
455 466
             output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, escape(force_unicode(option_label))))
456 467
         output.append(u'</ul>')
457  
-        return u'\n'.join(output)
  468
+        return mark_safe(u'\n'.join(output))
458 469
 
459 470
     def id_for_label(self, id_):
460 471
         # See the comment for RadioSelect.id_for_label()
@@ -560,3 +571,4 @@ def decompress(self, value):
560 571
         if value:
561 572
             return [value.date(), value.time().replace(microsecond=0)]
562 573
         return [None, None]
  574
+
43  django/oldforms/__init__.py
... ...
@@ -1,6 +1,7 @@
1 1
 from django.core import validators
2 2
 from django.core.exceptions import PermissionDenied
3 3
 from django.utils.html import escape
  4
+from django.utils.safestring import mark_safe
4 5
 from django.conf import settings
5 6
 from django.utils.translation import ugettext, ungettext
6 7
 from django.utils.encoding import smart_unicode, force_unicode
@@ -189,9 +190,9 @@ def errors(self):
189 190
 
190 191
     def html_error_list(self):
191 192
         if self.errors():
192  
-            return '<ul class="errorlist"><li>%s</li></ul>' % '</li><li>'.join([escape(e) for e in self.errors()])
  193
+            return mark_safe('<ul class="errorlist"><li>%s</li></ul>' % '</li><li>'.join([escape(e) for e in self.errors()]))
193 194
         else:
194  
-            return ''
  195
+            return mark_safe('')
195 196
 
196 197
     def get_id(self):
197 198
         return self.formfield.get_id()
@@ -226,7 +227,7 @@ def has_errors(self):
226 227
         return bool(len(self.errors()))
227 228
 
228 229
     def html_combined_error_list(self):
229  
-        return ''.join([field.html_error_list() for field in self.formfield_dict.values() if hasattr(field, 'errors')])
  230
+        return mark_safe(''.join([field.html_error_list() for field in self.formfield_dict.values() if hasattr(field, 'errors')]))
230 231
 
231 232
 class InlineObjectCollection(object):
232 233
     "An object that acts like a sparse list of form field collections."
@@ -418,9 +419,9 @@ def render(self, data):
418 419
         max_length = u''
419 420
         if self.max_length:
420 421
             max_length = u'maxlength="%s" ' % self.max_length
421  
-        return u'<input type="%s" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \
  422
+        return mark_safe(u'<input type="%s" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \
422 423
             (self.input_type, self.get_id(), self.__class__.__name__, self.is_required and u' required' or '',
423  
-            self.field_name, self.length, escape(data), max_length)
  424
+            self.field_name, self.length, escape(data), max_length))
424 425
 
425 426
     def html2python(data):
426 427
         return data
@@ -442,9 +443,9 @@ def __init__(self, field_name, rows=10, cols=40, is_required=False, validator_li
442 443
     def render(self, data):
443 444
         if data is None:
444 445
             data = ''
445  
-        return u'<textarea id="%s" class="v%s%s" name="%s" rows="%s" cols="%s">%s</textarea>' % \
  446
+        return mark_safe(u'<textarea id="%s" class="v%s%s" name="%s" rows="%s" cols="%s">%s</textarea>' % \
446 447
             (self.get_id(), self.__class__.__name__, self.is_required and u' required' or u'',
447  
-            self.field_name, self.rows, self.cols, escape(data))
  448
+            self.field_name, self.rows, self.cols, escape(data)))
448 449
 
449 450
 class HiddenField(FormField):
450 451
     def __init__(self, field_name, is_required=False, validator_list=None, max_length=None):
@@ -453,8 +454,8 @@ def __init__(self, field_name, is_required=False, validator_list=None, max_lengt
453 454
         self.validator_list = validator_list[:]
454 455
 
455 456
     def render(self, data):
456  
-        return u'<input type="hidden" id="%s" name="%s" value="%s" />' % \
457  
-            (self.get_id(), self.field_name, escape(data))
  457
+        return mark_safe(u'<input type="hidden" id="%s" name="%s" value="%s" />' % \
  458
+            (self.get_id(), self.field_name, escape(data)))
458 459
 
459 460
 class CheckboxField(FormField):
460 461
     def __init__(self, field_name, checked_by_default=False, validator_list=None, is_required=False):
@@ -468,9 +469,9 @@ def render(self, data):
468 469
         checked_html = ''
469 470
         if data or (data is '' and self.checked_by_default):
470 471
             checked_html = ' checked="checked"'
471  
-        return u'<input type="checkbox" id="%s" class="v%s" name="%s"%s />' % \
  472
+        return mark_safe(u'<input type="checkbox" id="%s" class="v%s" name="%s"%s />' % \
472 473
             (self.get_id(), self.__class__.__name__,
473  
-            self.field_name, checked_html)
  474
+            self.field_name, checked_html))
474 475
 
475 476
     def html2python(data):
476 477
         "Convert value from browser ('on' or '') to a Python boolean"
@@ -502,7 +503,7 @@ def render(self, data):
502 503
                 selected_html = u' selected="selected"'
503 504
             output.append(u'    <option value="%s"%s>%s</option>' % (escape(value), selected_html, force_unicode(escape(display_name))))
504 505
         output.append(u'  </select>')
505  
-        return u'\n'.join(output)
  506
+        return mark_safe(u'\n'.join(output))
506 507
 
507 508
     def isValidChoice(self, data, form):
508 509
         str_data = smart_unicode(data)
@@ -556,7 +557,7 @@ def __unicode__(self):
556 557
                 output = [u'<ul%s>' % (self.ul_class and u' class="%s"' % self.ul_class or u'')]
557 558
                 output.extend([u'<li>%s %s</li>' % (d['field'], d['label']) for d in self.datalist])
558 559
                 output.append(u'</ul>')
559  
-                return u''.join(output)
  560
+                return mark_safe(u''.join(output))
560 561
             def __iter__(self):
561 562
                 for d in self.datalist:
562 563
                     yield d
@@ -571,11 +572,11 @@ def __len__(self):
571 572
             datalist.append({
572 573
                 'value': value,
573 574
                 'name': display_name,
574  
-                'field': u'<input type="radio" id="%s" name="%s" value="%s"%s/>' % \
575  
-                    (self.get_id() + u'_' + unicode(i), self.field_name, value, selected_html),
576  
-                'label': u'<label for="%s">%s</label>' % \
  575
+                'field': mark_safe(u'<input type="radio" id="%s" name="%s" value="%s"%s/>' % \
  576
+                    (self.get_id() + u'_' + unicode(i), self.field_name, value, selected_html)),
  577
+                'label': mark_safe(u'<label for="%s">%s</label>' % \
577 578
                     (self.get_id() + u'_' + unicode(i), display_name),
578  
-            })
  579
+            )})
579 580
         return RadioFieldRenderer(datalist, self.ul_class)
580 581
 
581 582
     def isValidChoice(self, data, form):
@@ -614,7 +615,7 @@ def render(self, data):
614 615
                 selected_html = u' selected="selected"'
615 616
             output.append(u'    <option value="%s"%s>%s</option>' % (escape(value), selected_html, force_unicode(escape(choice))))
616 617
         output.append(u'  </select>')
617  
-        return u'\n'.join(output)
  618
+        return mark_safe(u'\n'.join(output))
618 619
 
619 620
     def isValidChoice(self, field_data, all_data):
620 621
         # data is something like ['1', '2', '3']
@@ -667,7 +668,7 @@ def render(self, data):
667 668
                 (self.get_id() + escape(value), self.__class__.__name__, field_name, checked_html,
668 669
                 self.get_id() + escape(value), choice))
669 670
         output.append(u'</ul>')
670  
-        return u'\n'.join(output)
  671
+        return mark_safe(u'\n'.join(output))
671