Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import custom jinja2 filters from another file (and using Flask)?

Tags:

I have a jinja_filters.py file with a few dozen custom filters I've written. Now I have multiple Flask apps that need to use these filters. (I'm not sure if my problem is Flask-specific or not.)

One hacky way to accomplish what I want is to do:

app = Flask(__name__)  import jinja_filters  @app.template_filter('filter_name1') def filter_name1(arg):     return jinja_filters.filter_name1(arg)  @app.template_filter('filter_name2') def filter_name2(arg):     return jinja_filters.filter_name2(arg)  ... 

What's the "right" way to do this?

EDIT: Ideally, I wouldn't have to list each filter name. So when I add a new filter to jinja_filters.py I don't have to update any other code -- all my apps would be able to use it right away.

like image 727
Dustin Boswell Avatar asked Sep 05 '12 19:09

Dustin Boswell


2 Answers

There is a recommended way of doing this using Flask blueprints. One of it's use cases is this functionality specifically:

  • Provide template filters, static files, templates, and other utilities through blueprints. A blueprint does not have to implement applications or view functions.

You just need to create a flask.Blueprint object and use it to register your filters in a similar way as you would with flask.Flask app object, using the Blueprint.app_template_filter decorator or Blueprint.add_app_template_filter method.

# filters.py  import jinja2 import flask  blueprint = flask.Blueprint('filters', __name__)  # using the decorator @jinja2.contextfilter @blueprint.app_template_filter() def filter1(context, value):     return 1  # using the method @jinja2.contextfilter def filter2(context, value):     return 2  blueprint.add_app_template_filter(filter2) 

Then you just need to register the blueprint on your app object:

# app.py  import flask import filters  app = flask.Flask(__name__) app.register_blueprint(filters.blueprint) 

And voilà, the filters are registered.

like image 134
famousgarkin Avatar answered Sep 17 '22 15:09

famousgarkin


Where ever you're setting up your app object (app.py, perhaps), you only need to import your custom filters and then modify the Jinja environment attribute.

import jinja_filters  app = Flask(__name__) app.jinja_env.filters['filter_name1'] = jinja_filters.filter_name1 app.jinja_env.filters['filter_name2'] = jinja_filters.filter_name2 

and so on.

Another possibility is to use the inspect module to find all the methods in jinja_filters like so:

from inspect import getmembers, isfunction import jinja_filters  app = Flask(__name__)  my_filters = {name: function                  for name, function in getmembers(jinja_filters)                 if isfunction(function)}  app.jinja_env.filters.update(my_filters) 

That code is untested, but the idea is to build a dictionary of function names and functions that exist in your jinja_filters files and then update the Jinja environment's filters dictionary with your filters.

like image 23
aezell Avatar answered Sep 19 '22 15:09

aezell