From fe150f3cec0bb62169f9e2a7b3cba4e6833b6a01 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 15 Mar 2010 02:42:41 +0100 Subject: [PATCH] Documented autoescaping behavior and eval contexts. --HG-- branch : trunk --- CHANGES | 3 +- docs/api.rst | 67 ++++++++++++++++++++++++++++++++++++++++++--- docs/extensions.rst | 14 ++++++++++ docs/templates.rst | 21 ++++++++++++++ jinja2/filters.py | 3 +- jinja2/utils.py | 3 +- 6 files changed, 104 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 7926e38..c0f24eb 100644 --- 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 ------------- diff --git a/docs/api.rst b/docs/api.rst index 35b4cf6..a1ea62c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -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'

%s

' % p.replace('\n', '
\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 diff --git a/docs/extensions.rst b/docs/extensions.rst index cfd79ef..707b155 100644 --- a/docs/extensions.rst +++ b/docs/extensions.rst @@ -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: diff --git a/docs/templates.rst b/docs/templates.rst index 087fb59..a14b8ac 100644 --- a/docs/templates.rst +++ b/docs/templates.rst @@ -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. diff --git a/jinja2/filters.py b/jinja2/filters.py index b7402de..c0b8bee 100644 --- a/jinja2/filters.py +++ b/jinja2/filters.py @@ -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 """ diff --git a/jinja2/utils.py b/jinja2/utils.py index e00dee2..1fd6ec5 100644 --- a/jinja2/utils.py +++ b/jinja2/utils.py @@ -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 """ -- 2.26.2