Documented autoescaping behavior and eval contexts.
authorArmin Ronacher <armin.ronacher@active-4.com>
Mon, 15 Mar 2010 01:42:41 +0000 (02:42 +0100)
committerArmin Ronacher <armin.ronacher@active-4.com>
Mon, 15 Mar 2010 01:42:41 +0000 (02:42 +0100)
--HG--
branch : trunk

CHANGES
docs/api.rst
docs/extensions.rst
docs/templates.rst
jinja2/filters.py
jinja2/utils.py

diff --git a/CHANGES b/CHANGES
index 7926e38a1950cb8ff9019ec1536d09e504016627..c0f24eb596dbd71b0fe62cbe07d1bedf69cb47ca 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -13,8 +13,9 @@ Version 2.4
   precompiled sources.  The environment now features a method
   to compile the templates from a configured loader into a zip
   file or folder.
-
 - the _speedups C extension now supports Python 3.
+- added support for autoescaping toggling sections and support
+  for evaluation contexts (:ref:`eval-context`).
 
 Version 2.3.1
 -------------
index 35b4cf624eb20c9ffe4a9190346314c3cfe1b2fd..a1ea62cbe6bd0a326f3edc26cfd4667857a8ce85 100644 (file)
@@ -353,6 +353,10 @@ The Context
         blocks registered.  The last item in each list is the current active
         block (latest in the inheritance chain).
 
+    .. attribute:: eval_ctx
+
+        The current :ref:`eval-context`.
+
     .. automethod:: jinja2.runtime.Context.call(callable, \*args, \**kwargs)
 
 
@@ -450,10 +454,14 @@ functions to a Jinja2 environment.
 
 .. autofunction:: jinja2.contextfilter
 
+.. autofunction:: jinja2.evalcontextfilter
+
 .. autofunction:: jinja2.environmentfunction
 
 .. autofunction:: jinja2.contextfunction
 
+.. autofunction:: jinja2.evalcontextfunction
+
 .. function:: escape(s)
 
     Convert the characters ``&``, ``<``, ``>``, ``'``, and ``"`` in string `s`
@@ -545,7 +553,8 @@ Inside the template it can then be used as follows:
 Filters can also be passed the current template context or environment.  This
 is useful if a filter wants to return an undefined value or check the current
 :attr:`~Environment.autoescape` setting.  For this purpose two decorators
-exist: :func:`environmentfilter` and :func:`contextfilter`.
+exist: :func:`environmentfilter`, :func:`contextfilter` and
+:func:`evalcontextfilter`.
 
 Here a small example filter that breaks a text into HTML line breaks and
 paragraphs and marks the return value as safe HTML string if autoescaping is
@@ -556,11 +565,11 @@ enabled::
 
     _paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
 
-    @environmentfilter
-    def nl2br(environment, value):
+    @evalcontextfilter
+    def nl2br(eval_ctx, value):
         result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n')
                               for p in _paragraph_re.split(escape(value)))
-        if environment.autoescape:
+        if eval_ctx.autoescape:
             result = Markup(result)
         return result
 
@@ -568,6 +577,56 @@ Context filters work the same just that the first argument is the current
 active :class:`Context` rather then the environment.
 
 
+.. _eval-context:
+
+Evaluation Context
+------------------
+
+The evaluation context (short eval context or eval ctx) is a new object
+introducted in Jinja 2.4 that makes it possible to activate and deactivate
+compiled features at runtime.
+
+Currently it is only used to enable and disable the automatic escaping but
+can be used for extensions as well.
+
+In previous Jinja versions filters and functions were marked as
+environment callables in order to check for the autoescape status from the
+environment.  In new versions it's encouraged to check the setting from the
+evaluation context instead.
+
+Previous versions::
+
+    @environmentfilter
+    def filter(env, value):
+        result = do_something(value)
+        if env.autoescape:
+            result = Markup(result)
+        return result
+
+In new versions you can either use a :func:`contextfilter` and access the
+evaluation context from the actual context, or use a
+:func:`evalcontextfilter` which directly passes the evaluation context to
+the function::
+
+    @contextfilter
+    def filter(context, value):
+        result = do_something(value)
+        if context.eval_ctx.autoescape:
+            result = Markup(result)
+        return result
+
+    @evalcontextfilter
+    def filter(eval_ctx, value):
+        result = do_something(value)
+        if eval_ctx.autoescape:
+            result = Markup(result)
+        return result
+
+The evaluation context must not be modified at runtime.  Modifications
+must only happen with a :class:`nodes.EvalContextModifier` and
+:class:`nodes.ScopedEvalContextModifier` from an extension, not on the
+eval context object itself.
+
 .. _writing-tests:
 
 Custom Tests
index cfd79eff5c3d311aaab749a805d3f99f4cee86b4..707b155596fbd130f9f4c8af0b973eadd73d223c 100644 (file)
@@ -126,6 +126,20 @@ 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.
 
+.. _autoescape-extension:
+
+Autoescape Extension
+--------------------
+
+**Import name:** `jinja2.ext.autoescape`
+
+.. versionadded:: 2.4
+
+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
+activated.  The setting overriding is scoped.
+
 
 .. _writing-extensions:
 
index 087fb59c5d11d86347dcec6b6f3616095f5ce967..a14b8ac52a04885177ece5b580e9257d886f2ea6 100644 (file)
@@ -1308,3 +1308,24 @@ are equivalent::
         {% set foo = 42 %}
         {{ foo }}
     {% endwith %}
+
+
+Autoescape Extension
+--------------------
+
+.. versionadded:: 2.4
+
+If the application enables the :ref:`autoescape-extension` one can
+activate and deactivate the autoescaping from within the templates.
+
+Example::
+
+    {% autoescape true %}
+        Autoescaping is active within this block
+    {% endautoescape %}
+
+    {% autoescape false %}
+        Autoescaping is inactive within this block
+    {% endautoescape %}
+
+After the `endautoescape` the behavior is reverted to what it was before.
index b7402de160b8b23a33fe6cd47ce2c145c2457c62..c0b8bee0b5e38ae76d025c5b2cf49411dbeb7d9a 100644 (file)
@@ -31,7 +31,8 @@ def contextfilter(f):
 
 def evalcontextfilter(f):
     """Decorator for marking eval-context dependent filters.  An eval
-    context object is passed as first argument.
+    context object is passed as first argument.  For more information
+    about the eval context, see :ref:`eval-context`.
 
     .. versionadded:: 2.4
     """
index e00dee21623851bed14085f7d49e9d3a3c85d65f..1fd6ec5dfd8215552bfb27b182a50e1a90aa07de 100644 (file)
@@ -131,7 +131,8 @@ def evalcontextfunction(f):
     """This decoraotr can be used to mark a function or method as an eval
     context callable.  This is similar to the :func:`contextfunction`
     but instead of passing the context, an evaluation context object is
-    passed.
+    passed.  For more information about the eval context, see
+    :ref:`eval-context`.
 
     .. versionadded:: 2.4
     """