From aa3d8398fd1a38b449b64fea4979f358f3c711e3 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 13 Jul 2010 23:30:29 +0200 Subject: [PATCH] Config is now available in templates, context processors no longer override keys --- CHANGES | 4 ++++ docs/upgrading.rst | 8 ++++++++ flask/app.py | 11 ++++++++++- flask/templating.py | 1 + tests/flask_tests.py | 24 ++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index db26bdc7..0c04a91d 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,10 @@ Release date to be announced, codename to be decided. for the module. This was implemented to aid GAE which will remove the static folder if it's part of a mapping in the .yml file. +- the :attr:`~flask.Flask.config` is now available in the templates + as `config`. +- context processors will no longer override values passed directly + to the render function. Version 0.5.1 ------------- diff --git a/docs/upgrading.rst b/docs/upgrading.rst index f3a7a27d..747fdb72 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -30,6 +30,14 @@ how other systems handle request pre- and postprocessing. If you dependend on the order of execution of post-request functions, be sure to change the order. +Another change that breaks backwards compatibility is that context +processors will no longer override values passed directly to the template +rendering function. If for example `request` is as variable passed +directly to the template, the default context processor will not override +it with the current request object. This makes it easier to extend +context processors later to inject additional variables without breaking +existing template not expecting them. + Version 0.5 ----------- diff --git a/flask/app.py b/flask/app.py index a70a930d..fd97bab4 100644 --- a/flask/app.py +++ b/flask/app.py @@ -343,7 +343,11 @@ class Flask(_PackageBoundObject): def update_template_context(self, context): """Update the template context with some commonly used variables. - This injects request, session and g into the template context. + This injects request, session, config and g into the template + context as well as everything template context processors want + to inject. Note that the as of Flask 0.6, the original values + in the context will not be overriden if a context processor + decides to return a value with the same key. :param context: the context as a dictionary that is updated in place to add extra variables. @@ -352,8 +356,13 @@ class Flask(_PackageBoundObject): mod = _request_ctx_stack.top.request.module if mod is not None and mod in self.template_context_processors: funcs = chain(funcs, self.template_context_processors[mod]) + orig_ctx = context.copy() for func in funcs: context.update(func()) + # make sure the original values win. This makes it possible to + # easier add new variables in context processors without breaking + # existing views. + context.update(orig_ctx) def run(self, host='127.0.0.1', port=5000, **options): """Runs the application on a local development server. If the diff --git a/flask/templating.py b/flask/templating.py index 23c55c2b..c55d4826 100644 --- a/flask/templating.py +++ b/flask/templating.py @@ -19,6 +19,7 @@ def _default_template_ctx_processor(): """ reqctx = _request_ctx_stack.top return dict( + config=reqctx.app.config, request=reqctx.request, session=reqctx.session, g=reqctx.g diff --git a/tests/flask_tests.py b/tests/flask_tests.py index 6c16bbd4..533afd21 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -492,6 +492,30 @@ class TemplatingTestCase(unittest.TestCase): rv = app.test_client().get('/') assert rv.data == '

23|42' + def test_original_win(self): + app = flask.Flask(__name__) + @app.route('/') + def index(): + return flask.render_template_string('{{ config }}', config=42) + rv = app.test_client().get('/') + assert rv.data == '42' + + def test_standard_context(self): + app = flask.Flask(__name__) + app.secret_key = 'development key' + @app.route('/') + def index(): + flask.g.foo = 23 + flask.session['test'] = 'aha' + return flask.render_template_string(''' + {{ request.args.foo }} + {{ g.foo }} + {{ config.DEBUG }} + {{ session.test }} + ''') + rv = app.test_client().get('/?foo=42') + assert rv.data.split() == ['42', '23', 'False', 'aha'] + def test_escaping(self): text = '

Hello World!' app = flask.Flask(__name__)