diff options
author | Christian Hausknecht <nelson@destiny.(none)> | 2010-03-09 15:35:37 +0100 |
---|---|---|
committer | Marcel Hellkamp <marc@gsites.de> | 2010-03-09 15:35:37 +0100 |
commit | 1f8f5fc458273d4d8608ec3f80b68cc2da24056c (patch) | |
tree | 4b921b69ea9451e69cab403063d77c1104b2f273 | |
parent | 77d5391dedb19459d570edcea71ab78b0c374abe (diff) | |
download | bottle-1f8f5fc458273d4d8608ec3f80b68cc2da24056c.tar.gz |
Allow passing arguments to the Jinja2 template prepare method.
-rwxr-xr-x | bottle.py | 39 | ||||
-rw-r--r-- | test/test_jinja2.py | 20 |
2 files changed, 50 insertions, 9 deletions
@@ -1272,13 +1272,17 @@ class BaseTemplate(object): """ Base class and minimal API for template adapters """ extentions = ['tpl','html','thtml','stpl'] - def __init__(self, source=None, name=None, lookup=[], encoding='utf8'): + def __init__(self, source=None, name=None, lookup=[], encoding='utf8', + filters=None, tests=None): """ Create a new template. If the source parameter (str or buffer) is missing, the name argument is used to guess a template filename. Subclasses can assume that either self.source or self.filename is set. Both are strings. The lookup-argument works similar to sys.path for templates. The encoding parameter is used to decode byte strings or files. + The parameters filters and tests are both jinja2 specific. The both + contains dicts of the form {'name': function, ...} in order to pass them + to jinja2.environment.filters or jinja2.environment..tests. """ self.name = name self.source = source.read() if hasattr(source, 'read') else source @@ -1291,7 +1295,7 @@ class BaseTemplate(object): raise TemplateError('Template %s not found.' % repr(name)) if not self.source and not self.filename: raise TemplateError('No template specified.') - self.prepare() + self.prepare(filters=filters, tests=tests) @classmethod def search(cls, name, lookup=[]): @@ -1324,7 +1328,7 @@ class MakoTemplate(BaseTemplate): default_filters=None global_variables={} - def prepare(self): + def prepare(self, **kwargs): from mako.template import Template from mako.lookup import TemplateLookup #TODO: This is a hack... http://github.com/defnull/bottle/issues#issue/8 @@ -1345,7 +1349,7 @@ class MakoTemplate(BaseTemplate): class CheetahTemplate(BaseTemplate): - def prepare(self): + def prepare(self, **kwargs): from Cheetah.Template import Template self.context = threading.local() self.context.vars = {} @@ -1364,10 +1368,21 @@ class CheetahTemplate(BaseTemplate): class Jinja2Template(BaseTemplate): env = None # hopefully, a Jinja environment is actually thread-safe prefix = "#" - def prepare(self): + def prepare(self, filters=None, tests=None): + """ + Both parameters are passed through the template function. + :param filters: dict with custom filters {"name": function} + :param tests: dict with custom tests {"name": function} + """ if not self.env: from jinja2 import Environment, FunctionLoader - self.env = Environment(line_statement_prefix=self.prefix, loader=FunctionLoader(self.loader)) + self.env = Environment(line_statement_prefix=self.prefix, + loader=FunctionLoader(self.loader) + ) + if filters: + self.env.filters.update(filters) + if tests: + self.env.tests.update(tests) if self.source: self.tpl = self.env.from_string(self.source) else: @@ -1387,7 +1402,7 @@ class SimpleTemplate(BaseTemplate): blocks = ('if','elif','else','except','finally','for','while','with','def','class') dedent_blocks = ('elif', 'else', 'except', 'finally') - def prepare(self): + def prepare(self, **kwargs): if self.source: self.code = self.translate(self.source) self.co = compile(self.code, '<string>', 'exec') @@ -1518,9 +1533,15 @@ def template(tpl, template_adapter=SimpleTemplate, **args): lookup = args.get('template_lookup', TEMPLATE_PATH) if tpl not in TEMPLATES or DEBUG: if "\n" in tpl or "{" in tpl or "%" in tpl or '$' in tpl: - TEMPLATES[tpl] = template_adapter(source=tpl, lookup=lookup) + TEMPLATES[tpl] = template_adapter(source=tpl, lookup=lookup, + filters=args.get('filters'), + tests=args.get('tests') + ) else: - TEMPLATES[tpl] = template_adapter(name=tpl, lookup=lookup) + TEMPLATES[tpl] = template_adapter(name=tpl, lookup=lookup, + filters=args.get('filters'), + tests=args.get('tests') + ) if not TEMPLATES[tpl]: abort(500, 'Template (%s) not found' % tpl) args['abort'] = abort diff --git a/test/test_jinja2.py b/test/test_jinja2.py index 985316a..9cdacad 100644 --- a/test/test_jinja2.py +++ b/test/test_jinja2.py @@ -1,6 +1,8 @@ +# -*- coding: utf-8 -*- import unittest from bottle import Jinja2Template + class TestJinja2Template(unittest.TestCase): def test_string(self): @@ -31,6 +33,24 @@ class TestJinja2Template(unittest.TestCase): t = Jinja2Template(name='jinja2_inherit', lookup=['./views/']).render() self.assertEqual('begin abc end', ''.join(t)) + def test_custom_filters(self): + """Templates: jinja2 custom filters """ + from bottle import jinja2_template as template + filters = {"star": lambda var: u"".join((u'*', var, u'*'))} + res = template("start {{var|star}} end", var="var", filters=filters) + self.assertEqual("start *var* end", res) + + def test_custom_tests(self): + """Templates: jinja2 custom tests """ + from bottle import jinja2_template as template + TEMPL = u"""{% if var is even %}gerade{% else %}ungerade{% endif %}""" + tests={"even": lambda x: False if x % 2 else True} + res = template(TEMPL, var=2, tests=tests) + self.assertEqual("gerade", res) + res = template(TEMPL, var=1, tests=tests) + self.assertEqual("ungerade", res) + + try: import jinja2 except ImportError: |