diff --git a/CHANGES b/CHANGES index 7f3374a1..eac9fad7 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,8 @@ Release date to be decided. :ref:`upgrading-to-010` for more information. - Added ``template_test`` methods in addition to the already existing ``template_filter`` method family. +- Added ``template_global`` methods in addition to the already existing + ``template_filter`` method family. - Set the content-length header for x-sendfile. - ``tojson`` filter now does not escape script blocks in HTML5 parsers. - Flask will now raise an error if you attempt to register a new function diff --git a/flask/app.py b/flask/app.py index f6d40be2..c9117727 100644 --- a/flask/app.py +++ b/flask/app.py @@ -1165,6 +1165,38 @@ class Flask(_PackageBoundObject): self.jinja_env.tests[name or f.__name__] = f + @setupmethod + def template_global(self, name=None): + """A decorator that is used to register a custom template global function. + You can specify a name for the global function, otherwise the function + name will be used. Example:: + + @app.template_global() + def double(n): + return 2 * n + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + def decorator(f): + self.add_template_global(f, name=name) + return f + return decorator + + @setupmethod + def add_template_global(self, f, name=None): + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + @setupmethod def before_request(self, f): """Registers a function to run before each request.""" diff --git a/flask/blueprints.py b/flask/blueprints.py index 7ce23bbc..4575ec9b 100644 --- a/flask/blueprints.py +++ b/flask/blueprints.py @@ -237,6 +237,34 @@ class Blueprint(_PackageBoundObject): state.app.jinja_env.tests[name or f.__name__] = f self.record_once(register_template) + def app_template_global(self, name=None): + """Register a custom template global, available application wide. Like + :meth:`Flask.template_global` but for a blueprint. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + def decorator(f): + self.add_app_template_global(f, name=name) + return f + return decorator + + def add_app_template_global(self, f, name=None): + """Register a custom template global, available application wide. Like + :meth:`Flask.add_template_global` but for a blueprint. Works exactly + like the :meth:`app_template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + def register_template(state): + state.app.jinja_env.globals[name or f.__name__] = f + self.record_once(register_template) + def before_request(self, f): """Like :meth:`Flask.before_request` but for a blueprint. This function is only executed before each request that is handled by a function of diff --git a/flask/testsuite/templating.py b/flask/testsuite/templating.py index 6345b710..635210f7 100644 --- a/flask/testsuite/templating.py +++ b/flask/testsuite/templating.py @@ -256,6 +256,18 @@ class TemplatingTestCase(FlaskTestCase): rv = app.test_client().get('/') self.assert_('Success!' in rv.data) + def test_add_template_global(self): + app = flask.Flask(__name__) + @app.template_global() + def get_stuff(): + return 42 + self.assert_('get_stuff' in app.jinja_env.globals.keys()) + self.assert_equal(app.jinja_env.globals['get_stuff'], get_stuff) + self.assert_(app.jinja_env.globals['get_stuff'](), 42) + with app.app_context(): + rv = flask.render_template_string('{{ get_stuff() }}') + self.assert_equal(rv, '42') + def test_custom_template_loader(self): class MyFlask(flask.Flask): def create_global_jinja_loader(self):