summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2013-10-15 14:43:35 -0700
committerAlex Gaynor <alex.gaynor@gmail.com>2013-10-15 14:43:35 -0700
commit694d7da6c53b9ad35381dccdf4f688771b0b932e (patch)
tree96811e80960024bec8319ff72eedf8a16720e497
parent6138186848d2d03f8f15e4071dd2b10de9753c7f (diff)
parentaf64429b991471b7a441e133b5b7d29070984f24 (diff)
Merge pull request #1744 from unaizalakain/ticket_7261
Fixed #7261 -- support for __html__ for library interoperability
-rw-r--r--django/utils/html.py4
-rw-r--r--django/utils/safestring.py8
-rw-r--r--tests/utils_tests/test_html.py8
-rw-r--r--tests/utils_tests/test_safestring.py6
4 files changed, 21 insertions, 5 deletions
diff --git a/django/utils/html.py b/django/utils/html.py
index 75eff0083d..825f139070 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -65,8 +65,8 @@ def conditional_escape(text):
"""
Similar to escape(), except that it doesn't operate on pre-escaped strings.
"""
- if isinstance(text, SafeData):
- return text
+ if hasattr(text, '__html__'):
+ return text.__html__()
else:
return escape(text)
diff --git a/django/utils/safestring.py b/django/utils/safestring.py
index bec59385f7..aee6427b3c 100644
--- a/django/utils/safestring.py
+++ b/django/utils/safestring.py
@@ -30,7 +30,13 @@ else:
EscapeUnicode = EscapeText
class SafeData(object):
- pass
+ def __html__(self):
+ """
+ Returns the html representation of a string.
+
+ Allows interoperability with other template engines.
+ """
+ return self
class SafeBytes(bytes, SafeData):
"""
diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py
index 74d94ea19d..28e9e326e0 100644
--- a/tests/utils_tests/test_html.py
+++ b/tests/utils_tests/test_html.py
@@ -5,7 +5,7 @@ from datetime import datetime
import os
from unittest import TestCase
-from django.utils import html
+from django.utils import html, safestring
from django.utils._os import upath
from django.utils.encoding import force_text
@@ -192,3 +192,9 @@ class TestUtilsHtml(TestCase):
self.assertEqual(quote('http://example.com/path/öäü/'), 'http://example.com/path/%C3%B6%C3%A4%C3%BC/')
self.assertEqual(quote('http://example.com/%C3%B6/ä/'), 'http://example.com/%C3%B6/%C3%A4/')
self.assertEqual(quote('http://example.com/?x=1&y=2'), 'http://example.com/?x=1&y=2')
+
+ def test_conditional_escape(self):
+ s = '<h1>interop</h1>'
+ self.assertEqual(html.conditional_escape(s),
+ '&lt;h1&gt;interop&lt;/h1&gt;')
+ self.assertEqual(html.conditional_escape(safestring.mark_safe(s)), s)
diff --git a/tests/utils_tests/test_safestring.py b/tests/utils_tests/test_safestring.py
index 5d4528a9a8..4673b26ac7 100644
--- a/tests/utils_tests/test_safestring.py
+++ b/tests/utils_tests/test_safestring.py
@@ -4,7 +4,7 @@ from django.template import Template, Context
from django.test import TestCase
from django.utils.encoding import force_text, force_bytes
from django.utils.functional import lazy, Promise
-from django.utils.html import escape, conditional_escape
+from django.utils.html import escape
from django.utils.safestring import mark_safe, mark_for_escaping
from django.utils import six
from django.utils import translation
@@ -50,3 +50,7 @@ class SafeStringTest(TestCase):
s = mark_safe(translation.ugettext_lazy("username"))
with translation.override('fr'):
self.assertRenderEqual('{{ s }}', "nom d'utilisateur", s=s)
+
+ def test_html(self):
+ s = '<h1>interop</h1>'
+ self.assertEqual(s, mark_safe(s).__html__())