I have been experimenting with Bottle lately. I have done a bit of Django development and I've always liked its template engine, especially the idea of template inheritance and the fact that it's not a layer on top of xml. So, when starting to experiment with Bottle, I wanted to use Jinja2 as that was inspired by the Django template engine.
One of the nice features of Jinja2 (and its inspiration) are filters. For
example, in a template, one can use
{{ name|capitalized }}
which will output
the value of name
, but then capitalized. As this is merely for
presentation, I think this actually belongs in the template.
You can even write your own filters, which are basically just python functions
that are being called by the parser. However, I could not really find a clear
explanation of how to automatically use my custom filters in the
@view(templatename)
decorator offered by bottle. Here is the solution I came
up with:
from bottle import jinja2_view
view = functools.partial(jinja2_view,
template_settings={'filters': filter_dict})
where filter_dict
is a dictionary with a name to function mapping.
functools.partial
is a nice function (that is actually used in the bottle
definition of jinja2_view
as well), that allows you to wrap a function such
that certain (keyword) arguments already filled in. In other words: the above
code creates a new function that calls jinja2_view
with the
template_settings
argument already filled in. Now, you don't have to pass
template_settings
each time you call view
.
To automate adding filters to the filter_dict
as much as possible, I wrote a
simple @filter
decorator:
filter_dict = {}
def filter(func):
"""Decorator to add the function to filter_dict"""
filter_dict[func.__name__] = func
return func
# Usage:
@filter
def quote(s):
return urllib.quote(s)