Flask custom template loaders

Created 2014-11-09 Modified 2018-03-30

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