diff --git a/flask.py b/flask.py index 0993e6a0..1ba6e4d1 100644 --- a/flask.py +++ b/flask.py @@ -12,6 +12,7 @@ from __future__ import with_statement import os import sys +import types from itertools import chain from jinja2 import Environment, PackageLoader, FileSystemLoader @@ -825,6 +826,23 @@ class Flask(_PackageBoundObject): return f return decorator + def template_filter(self, name=None): + """A decorator that is used to register custom template filter. + You can specify a name for the filter, otherwise the function + name will be used. Example:: + + @app.template_filter() + def reverse(s): + return s[::-1] + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + def decorator(f): + self.jinja_env.filters[name or f.__name__] = f + return f + return decorator + def before_request(self, f): """Registers a function to run before each request.""" self.before_request_funcs.setdefault(None, []).append(f) diff --git a/tests/flask_tests.py b/tests/flask_tests.py index 7851bc75..6a4ae50c 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -311,6 +311,46 @@ class TemplatingTestCase(unittest.TestCase): macro = flask.get_template_attribute('_macro.html', 'hello') assert macro('World') == 'Hello World!' + def test_template_filter(self): + app = flask.Flask(__name__) + @app.template_filter() + def my_reverse(s): + return s[::-1] + assert 'my_reverse' in app.jinja_env.filters.keys() + assert app.jinja_env.filters['my_reverse'] == my_reverse + assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' + + def test_template_filter_with_name(self): + app = flask.Flask(__name__) + @app.template_filter('strrev') + def my_reverse(s): + return s[::-1] + assert 'strrev' in app.jinja_env.filters.keys() + assert app.jinja_env.filters['strrev'] == my_reverse + assert app.jinja_env.filters['strrev']('abcd') == 'dcba' + + def test_template_filter_with_template(self): + app = flask.Flask(__name__) + @app.template_filter() + def super_reverse(s): + return s[::-1] + @app.route('/') + def index(): + return flask.render_template('template_filter.html', value='abcd') + rv = app.test_client().get('/') + assert rv.data == 'dcba' + + def test_template_filter_with_name_and_template(self): + app = flask.Flask(__name__) + @app.template_filter('super_reverse') + def my_reverse(s): + return s[::-1] + @app.route('/') + def index(): + return flask.render_template('template_filter.html', value='abcd') + rv = app.test_client().get('/') + assert rv.data == 'dcba' + class ModuleTestCase(unittest.TestCase): diff --git a/tests/templates/template_filter.html b/tests/templates/template_filter.html new file mode 100644 index 00000000..af46cd94 --- /dev/null +++ b/tests/templates/template_filter.html @@ -0,0 +1 @@ +{{ value|super_reverse }} \ No newline at end of file