KalyanChakravarthy.net

home photos apps about

Flask custom template loaders

Sun 09 November 2014

Flask is amazing. The templating system called jinja2 packed with it is equally amazing.

The default behaviour of flask app is to look for template files specified in app.template_folder directory. Although this will work in most use-cases, sometimes you need additional control over this - for example if you have user specific templates or if you want to load templates from a database, dynamically.

This can be accomplished, by initialising app.jinja_loader with a custom Loader.

Jinja2 ships with serveral different loaders by default. The easiest one is DictLoader, which simply loads tempalte sfrom a dictionary.

from flask import Flask
import jinja2

app = Flask(__name__)
app.jinja_loader = jinja2.DictLoader({
        'index.html' : """
            {% extends 'base.html' %}
            {% block text %}
            Super cool!
            {% endblock %}
        """,

        'base.html' : """
            <b>{{ self.text() }}</b>
        """

    })

@app.route('/')
def doHome():
    return render_template('index.html')

The above example was fairly simple - it still pre-loads all templates. If there is a non-trivial requirement where you want to load them from database, then you can use FunctionLoader

def load_template(template_name):
    is_uptodate = True
    if template_name == 'index.html':
        return ("""
            {% extends 'base.html' %}
            {% block text %}
            Super cool!
            {% endblock %}
        """, None, is_uptodate)

    if template_name == 'base.html':
        return ("""
            <b>{{ self.text() }}</b>
        """, None, is_uptodate)


app.jinja_loader = jinja2.FunctionLoader(load_template)

Jinja2 ships with the following loaders, all of which can be used with flask

  • FileSystemLoader
  • PackageLoader
  • DictLoader
  • FunctionLoader
  • PrefixLoader
  • ChoiceLoader
  • ModuleLoader