Move the autoescape extension and with statement to be built-in
diff --git a/CHANGES b/CHANGES
index bd0dc75..afc6f76 100644
--- a/CHANGES
+++ b/CHANGES
@@ -40,6 +40,7 @@
between the different include and import constructs. Context is now always
propagated the same way. The only remaining differences is the defaults
for `with context` and `without context`.
+- The `with` and `autoescape` tags are now built-in.
Version 2.8.2
-------------
diff --git a/docs/api.rst b/docs/api.rst
index 3b5bccd..b7c25d3 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -247,12 +247,14 @@
Autoescaping
------------
-.. versionadded:: 2.4
+.. versionchanged:: 2.4
-As of Jinja 2.4 the preferred way to do autoescaping is to enable the
-:ref:`autoescape-extension` and to configure a sensible default for
-autoescaping. This makes it possible to enable and disable autoescaping
-on a per-template basis (HTML versus text for instance).
+Jinja2 now comes with autoescaping support. As of Jinja 2.9 the
+autoescape extension is removed and built-in. However autoescaping is
+not yet enabled by default though this might change in the future.
+It's recommended to configure a sensible default for autoescaping. This
+makes it possible to enable and disable autoescaping on a per-template
+basis (HTML versus text for instance).
Here a recommended setup that enables autoescaping for templates ending
in ``'.html'``, ``'.htm'`` and ``'.xml'`` and disabling it by default
@@ -265,8 +267,7 @@
return ext in ('html', 'htm', 'xml')
env = Environment(autoescape=guess_autoescape,
- loader=PackageLoader('mypackage'),
- extensions=['jinja2.ext.autoescape'])
+ loader=PackageLoader('mypackage'))
When implementing a guessing autoescape function, make sure you also
accept `None` as valid template name. This will be passed when generating
diff --git a/docs/extensions.rst b/docs/extensions.rst
index afdfb00..635d1e4 100644
--- a/docs/extensions.rst
+++ b/docs/extensions.rst
@@ -183,12 +183,9 @@
**Import name:** `jinja2.ext.with_`
-.. versionadded:: 2.3
+.. versionchanged:: 2.9
-This extension adds support for the with keyword. Using this keyword it
-is possible to enforce a nested scope in a template. Variables can be
-declared directly in the opening block of the with statement or using a
-standard `set` statement directly within.
+This extension is now built-in and no longer does anything.
.. _autoescape-extension:
@@ -197,12 +194,10 @@
**Import name:** `jinja2.ext.autoescape`
-.. versionadded:: 2.4
+.. versionchanged:: 2.9
-The autoescape extension allows you to toggle the autoescape feature from
-within the template. If the environment's :attr:`~Environment.autoescape`
-setting is set to `False` it can be activated, if it's `True` it can be
-deactivated. The setting overriding is scoped.
+This extension was removed and is now built-in. Enabling the extension
+no longer does anything.
.. _writing-extensions:
diff --git a/docs/templates.rst b/docs/templates.rst
index 9c3e7d5..48f1894 100644
--- a/docs/templates.rst
+++ b/docs/templates.rst
@@ -1460,10 +1460,8 @@
.. versionadded:: 2.3
-If the application enables the :ref:`with-extension`, it is possible to
-use the `with` keyword in templates. This makes it possible to create
-a new inner scope. Variables set within this scope are not visible
-outside of the scope.
+The with statement makes it possible to create a new inner scope.
+Variables set within this scope are not visible outside of the scope.
With in a nutshell::
@@ -1486,15 +1484,20 @@
{{ foo }}
{% endwith %}
+.. admonition:: Extension
+
+ In older versions of Jinja (before 2.9) it was required to enable this
+ feature with an extension. It's now enabled by default.
+
.. _autoescape-overrides:
-Autoescape Extension
+Autoescape Overrides
--------------------
.. versionadded:: 2.4
-If the application enables the :ref:`autoescape-extension`, one can
-activate and deactivate the autoescaping from within the templates.
+If you want you can activate and deactivate the autoescaping from within
+the templates.
Example::
@@ -1507,3 +1510,8 @@
{% endautoescape %}
After an `endautoescape` the behavior is reverted to what it was before.
+
+.. admonition:: Extension
+
+ In older versions of Jinja (before 2.9) it was required to enable this
+ feature with an extension. It's now enabled by default.
diff --git a/jinja2/ext.py b/jinja2/ext.py
index 562ab50..2735dbb 100644
--- a/jinja2/ext.py
+++ b/jinja2/ext.py
@@ -411,38 +411,11 @@
class WithExtension(Extension):
- """Adds support for a django-like with block."""
- tags = set(['with'])
-
- def parse(self, parser):
- node = nodes.Scope(lineno=next(parser.stream).lineno)
- assignments = []
- while parser.stream.current.type != 'block_end':
- lineno = parser.stream.current.lineno
- if assignments:
- parser.stream.expect('comma')
- target = parser.parse_assign_target()
- parser.stream.expect('assign')
- expr = parser.parse_expression()
- assignments.append(nodes.Assign(target, expr, lineno=lineno))
- node.body = assignments + \
- list(parser.parse_statements(('name:endwith',),
- drop_needle=True))
- return node
+ pass
class AutoEscapeExtension(Extension):
- """Changes auto escape rules for a scope."""
- tags = set(['autoescape'])
-
- def parse(self, parser):
- node = nodes.ScopedEvalContextModifier(lineno=next(parser.stream).lineno)
- node.options = [
- nodes.Keyword('autoescape', parser.parse_expression())
- ]
- node.body = parser.parse_statements(('name:endautoescape',),
- drop_needle=True)
- return nodes.Scope([node])
+ pass
def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS,
diff --git a/jinja2/parser.py b/jinja2/parser.py
index 00e0558..8c3cd5b 100644
--- a/jinja2/parser.py
+++ b/jinja2/parser.py
@@ -16,7 +16,7 @@
_statement_keywords = frozenset(['for', 'if', 'block', 'extends', 'print',
'macro', 'include', 'from', 'import',
- 'set'])
+ 'set', 'with', 'autoescape'])
_compare_operators = frozenset(['eq', 'ne', 'lt', 'lteq', 'gt', 'gteq'])
_math_nodes = {
@@ -224,6 +224,31 @@
break
return result
+ def parse_with(self):
+ node = nodes.Scope(lineno=next(self.stream).lineno)
+ assignments = []
+ while self.stream.current.type != 'block_end':
+ lineno = self.stream.current.lineno
+ if assignments:
+ self.stream.expect('comma')
+ target = self.parse_assign_target()
+ self.stream.expect('assign')
+ expr = self.parse_expression()
+ assignments.append(nodes.Assign(target, expr, lineno=lineno))
+ node.body = assignments + \
+ list(self.parse_statements(('name:endwith',),
+ drop_needle=True))
+ return node
+
+ def parse_autoescape(self):
+ node = nodes.ScopedEvalContextModifier(lineno=next(self.stream).lineno)
+ node.options = [
+ nodes.Keyword('autoescape', self.parse_expression())
+ ]
+ node.body = self.parse_statements(('name:endautoescape',),
+ drop_needle=True)
+ return nodes.Scope([node])
+
def parse_block(self):
node = nodes.Block(lineno=next(self.stream).lineno)
node.name = self.stream.expect('name').value