Custom template folders with Flask

Someone was asking on [Flask][flask]’s IRC channel [#pocoo][irc] about sharing templates across more than one app but allowing each app to override the templates (pretty much what [Django’s TEMPLATE_DIRS setting][django] is for). One way of doing this would be to customise the Jinja2 template loader.

Here’s a trivial Flask app that searches for templates first in the default folder (‘templates’ in the same folder as the app) and then in an extra folder.

import flask
import jinja2

app = flask.Flask(__name__)
my_loader = jinja2.ChoiceLoader([
app.jinja_loader,
jinja2.FileSystemLoader(‘/path/to/extra/templates’),
])
app.jinja_loader = my_loader

@app.route(‘/’)
def home():
return flask.render_template(‘home.html’)

if __name__ == “__main__”:
app.run()

The only thing special here is creating a new template loader and then assigning it to [the `jinja_loader` attribute on the Flask application][attr]. [`ChoiceLoader`][choice] will search for a named template in the order of the loaders, stopping on the first match. In this example I re-used the loader that is created by default for an app, which is roughly like `FileSystemLoader(‘/path/to/app/templates’)`. There are [all kinds of other exciting template loaders available][loaders].

I really like the fact that Flask and Bottle’s APIs are so similar. Next I want Flask to include [Bottle’s template wrapping decorator][view] by default (there’s [a recipe in the Flask docs][templated]) and for both of them to re-name it `@template`.

[flask]: http://flask.pocoo.org/
[irc]: http://flask.pocoo.org/community/irc/
[attr]: http://flask.pocoo.org/docs/api/#flask.Flask.jinja_loader
[choice]: http://jinja.pocoo.org/docs/api/#jinja2.ChoiceLoader
[loaders]: http://jinja.pocoo.org/docs/api/#loaders
[django]: https://docs.djangoproject.com/en/dev/ref/templates/api/#loading-templates
[templated]: http://flask.pocoo.org/docs/patterns/viewdecorators/#templating-decorator
[view]: http://bottlepy.org/docs/stable/api.html#bottle.view

3 thoughts on “Custom template folders with Flask

  1. JR

    I just wanted to comment to say that I rolled my own terrible version of this functionality that included way too many calls to os.path.exists(), then got frustrated and found this post, which simplified my app dramatically. Thanks for shedding some light on this.

  2. Giovanni

    In case anyone is having problems: this doesn’t work in Heroku. You have to pass the path without the first ‘/’.
    Like 'flaskapp/userdata'

Leave a Reply

Your email address will not be published. Required fields are marked *