/usr/lib/python2.7/dist-packages/jingo/monkey.py is in python-jingo 0.7-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | """
Django marks its form HTML "safe" according to its own rules, which Jinja2 does
not recognize.
This monkeypatches Django to support the ``__html__`` protocol used in Jinja2
templates. ``Form``, ``BoundField``, ``ErrorList``, and other form objects that
render HTML through their ``__unicode__`` method are extended with ``__html__``
so they can be rendered in Jinja2 templates without adding ``|safe``.
Call the ``patch()`` function to execute the patch. It must be called
before ``django.forms`` is imported for the conditional_escape patch to work
properly. The root URLconf is the recommended location for calling ``patch()``.
Usage::
import jingo.monkey
jingo.monkey.patch()
This patch was originally developed by Jeff Balogh and this version is taken
from the nuggets project at
https://github.com/mozilla/nuggets/blob/master/safe_django_forms.py
"""
from __future__ import unicode_literals
import django.utils.encoding
import django.utils.html
import django.utils.safestring
from django.utils import six
# This function gets directly imported within Django, so this change needs to
# happen before too many Django imports happen.
def conditional_escape(html):
"""
Similar to escape(), except that it doesn't operate on pre-escaped strings.
"""
if hasattr(html, '__html__'):
return html.__html__()
elif isinstance(html, django.utils.safestring.SafeData):
return html
return django.utils.html.escape(html)
# Django uses SafeData to mark a string that has already been escaped or
# otherwise deemed safe. This __html__ method lets Jinja know about that too.
def __html__(self):
"""
Returns the html representation of a string.
Allows interoperability with other template engines.
"""
return six.text_type(self)
class StrAndUnicode(object):
"""
A class whose __str__ returns its __unicode__ as a UTF-8 bytestring.
Useful as a mix-in.
"""
def __str__(self):
return self.__unicode__().encode('utf-8')
# Django uses StrAndUnicode for classes like Form, BoundField, Widget which
# have a __unicode__ method which returns escaped html. We replace
# StrAndUnicode with SafeStrAndUnicode to get the __html__ method.
class SafeStrAndUnicode(StrAndUnicode):
"""A class whose __str__ and __html__ returns __unicode__."""
def __html__(self):
return six.text_type(self)
def patch():
django.utils.html.conditional_escape = conditional_escape
django.utils.safestring.SafeData.__html__ = __html__
# forms imports have to come after we patch conditional_escape.
from django.forms import forms, formsets, util, widgets
# Replace StrAndUnicode with SafeStrAndUnicode in the inheritance
# for all these classes.
classes = (
forms.BaseForm,
forms.BoundField,
formsets.BaseFormSet,
util.ErrorDict,
util.ErrorList,
widgets.Media,
widgets.RadioInput,
widgets.RadioFieldRenderer,
)
for cls in classes:
bases = list(cls.__bases__)
if StrAndUnicode in bases:
idx = bases.index(StrAndUnicode)
bases[idx] = SafeStrAndUnicode
cls.__bases__ = tuple(bases)
for cls in classes:
if not hasattr(cls, '__html__'):
cls.__html__ = __html__
|