summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Elliot Ross <aaronelliotross@gmail.com>2015-11-08 10:06:07 +0100
committerTim Graham <timograham@gmail.com>2015-11-12 19:14:23 -0500
commit19a5f6da329d58653bcda85f84efd5d5eaf68f84 (patch)
tree52f6955cff728d3050710f70ba0a735e99704643
parenta8f05f405f8b78e13d7c4c9ffd73d6182b6fc4d5 (diff)
Fixed #25469 -- Added autoescape option to DjangoTemplates backend.
Thanks Aymeric for the initial patch and Carl for review.
-rw-r--r--django/template/backends/django.py3
-rw-r--r--django/template/context.py10
-rw-r--r--django/template/engine.py3
-rw-r--r--docs/ref/templates/api.txt14
-rw-r--r--docs/releases/1.10.txt4
-rw-r--r--docs/topics/templates.txt13
-rw-r--r--tests/template_backends/test_django.py22
7 files changed, 60 insertions, 9 deletions
diff --git a/django/template/backends/django.py b/django/template/backends/django.py
index af58f60b2a..cc795aae1c 100644
--- a/django/template/backends/django.py
+++ b/django/template/backends/django.py
@@ -23,6 +23,7 @@ class DjangoTemplates(BaseEngine):
def __init__(self, params):
params = params.copy()
options = params.pop('OPTIONS').copy()
+ options.setdefault('autoescape', True)
options.setdefault('debug', settings.DEBUG)
options.setdefault('file_charset', settings.FILE_CHARSET)
libraries = options.get('libraries', {})
@@ -60,7 +61,7 @@ class Template(object):
return self.template.origin
def render(self, context=None, request=None):
- context = make_context(context, request)
+ context = make_context(context, request, autoescape=self.backend.engine.autoescape)
try:
return self.template.render(context)
except TemplateDoesNotExist as exc:
diff --git a/django/template/context.py b/django/template/context.py
index 2643e927f4..04d0e2f5f4 100644
--- a/django/template/context.py
+++ b/django/template/context.py
@@ -201,9 +201,9 @@ class RequestContext(Context):
Additional processors can be specified as a list of callables
using the "processors" keyword argument.
"""
- def __init__(self, request, dict_=None, processors=None, use_l10n=None, use_tz=None):
+ def __init__(self, request, dict_=None, processors=None, use_l10n=None, use_tz=None, autoescape=True):
super(RequestContext, self).__init__(
- dict_, use_l10n=use_l10n, use_tz=use_tz)
+ dict_, use_l10n=use_l10n, use_tz=use_tz, autoescape=autoescape)
self.request = request
self._processors = () if processors is None else tuple(processors)
self._processors_index = len(self.dicts)
@@ -245,17 +245,17 @@ class RequestContext(Context):
return new_context
-def make_context(context, request=None):
+def make_context(context, request=None, **kwargs):
"""
Create a suitable Context from a plain dict and optionally an HttpRequest.
"""
if request is None:
- context = Context(context)
+ context = Context(context, **kwargs)
else:
# The following pattern is required to ensure values from
# context override those from template context processors.
original_context = context
- context = RequestContext(request)
+ context = RequestContext(request, **kwargs)
if original_context:
context.push(original_context)
return context
diff --git a/django/template/engine.py b/django/template/engine.py
index d439f49679..b49ed09088 100644
--- a/django/template/engine.py
+++ b/django/template/engine.py
@@ -18,7 +18,7 @@ class Engine(object):
def __init__(self, dirs=None, app_dirs=False, context_processors=None,
debug=False, loaders=None, string_if_invalid='',
- file_charset='utf-8', libraries=None, builtins=None):
+ file_charset='utf-8', libraries=None, builtins=None, autoescape=True):
if dirs is None:
dirs = []
if context_processors is None:
@@ -38,6 +38,7 @@ class Engine(object):
self.dirs = dirs
self.app_dirs = app_dirs
+ self.autoescape = autoescape
self.context_processors = context_processors
self.debug = debug
self.loaders = loaders
diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
index 570ffbc9d6..aaa08cc70b 100644
--- a/docs/ref/templates/api.txt
+++ b/docs/ref/templates/api.txt
@@ -48,7 +48,7 @@ probably isn't the documentation you're looking for. An instance of the
of that backend and any attribute defaults mentioned below are overridden by
what's passed by :class:`~django.template.backends.django.DjangoTemplates`.
-.. class:: Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None)
+.. class:: Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None, autoescape=True)
When instantiating an ``Engine`` all arguments must be passed as keyword
arguments:
@@ -63,6 +63,18 @@ what's passed by :class:`~django.template.backends.django.DjangoTemplates`.
It defaults to ``False``.
+ * ``autoescape`` controls whether HTML autoescaping is enabled.
+
+ It defaults to ``True``.
+
+ .. warning::
+
+ Only set it to ``False`` if you're rendering non-HTML templates!
+
+ .. versionadded:: 1.10
+
+ The ``autoescape`` option was added.
+
* ``context_processors`` is a list of dotted Python paths to callables
that are used to populate the context when a template is rendered with a
request. These callables take a request object as their argument and
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index 1f3857ab28..6dbe0362b9 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -204,7 +204,9 @@ Signals
Templates
^^^^^^^^^
-* ...
+* Added the ``autoescape`` option to the
+ :class:`~django.template.backends.django.DjangoTemplates` backend and the
+ :class:`~django.template.Engine` class.
Tests
^^^^^
diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt
index f0abccc835..4834e9eb06 100644
--- a/docs/topics/templates.txt
+++ b/docs/topics/templates.txt
@@ -295,6 +295,19 @@ applications. This generic name was kept for backwards-compatibility.
``DjangoTemplates`` engines accept the following :setting:`OPTIONS
<TEMPLATES-OPTIONS>`:
+* ``'autoescape'``: a boolean that controls whether HTML autoescaping is
+ enabled.
+
+ It defaults to ``True``.
+
+ .. warning::
+
+ Only set it to ``False`` if you're rendering non-HTML templates!
+
+ .. versionadded:: 1.10
+
+ The ``autoescape`` option was added.
+
* ``'context_processors'``: a list of dotted Python paths to callables that
are used to populate the context when a template is rendered with a request.
These callables take a request object as their argument and return a
diff --git a/tests/template_backends/test_django.py b/tests/template_backends/test_django.py
index 8d13aaee08..1a93a82274 100644
--- a/tests/template_backends/test_django.py
+++ b/tests/template_backends/test_django.py
@@ -1,5 +1,6 @@
from template_tests.test_response import test_processor_name
+from django.template import EngineHandler
from django.template.backends.django import DjangoTemplates
from django.template.library import InvalidTemplateLibrary
from django.test import RequestFactory, override_settings
@@ -108,3 +109,24 @@ class DjangoTemplatesTests(TemplateStringsTests):
'template_backends.apps.good.templatetags.good_tags',
]
)
+
+ def test_autoescape_off(self):
+ templates = [{
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'OPTIONS': {'autoescape': False},
+ }]
+ engines = EngineHandler(templates=templates)
+ self.assertEqual(
+ engines['django'].from_string('Hello, {{ name }}').render({'name': 'Bob & Jim'}),
+ 'Hello, Bob & Jim'
+ )
+
+ def test_autoescape_default(self):
+ templates = [{
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ }]
+ engines = EngineHandler(templates=templates)
+ self.assertEqual(
+ engines['django'].from_string('Hello, {{ name }}').render({'name': 'Bob & Jim'}),
+ 'Hello, Bob &amp; Jim'
+ )