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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With