Jinja
Template Loaders
This part of the documentation explains how to use and write a template loader.
Builtin Loaders
- ChoiceLoader
A loader that tries multiple loaders in the order they are given to the ChoiceLoader:
from jinja import ChoiceLoader, FileSystemLoader loader1 = FileSystemLoader("templates1") loader2 = FileSystemLoader("templates2") loader = ChoiceLoader([loader1, loader2])
- DictLoader
Load templates from a given dict:
from jinja import Environment, DictLoader e = Environment(loader=DictLoader(dict( layout='...', index='{% extends 'layout' %}...' )))
- FileSystemLoader
Loads templates from the filesystem:
from jinja import Environment, FileSystemLoader e = Environment(loader=FileSystemLoader('templates/'))
You can pass the following keyword arguments to the loader on initialisation:
searchpath String with the path to the templates on the filesystem. use_memcache Set this to True to enable memory caching. This is usually a good idea in production mode, but disable it during development since it won't reload template changes automatically. This only works in persistent environments like FastCGI. memcache_size Number of template instance you want to cache. Defaults to 40. cache_folder Set this to an existing directory to enable caching of templates on the file system. Note that this only affects templates transformed into python code. Default is None which means that caching is disabled. auto_reload Set this to False for a slightly better performance. In that case Jinja won't check for template changes on the filesystem. - FunctionLoader
Loads templates by calling a function which has to return a string or None if an error occoured.
from jinja import Environment, FunctionLoader def my_load_func(template_name): if template_name == 'foo': return '...' e = Environment(loader=FunctionLoader(my_load_func))
Because the interface is limited there is no way to cache such templates. Usually you should try to use a loader with a more solid backend.
You can pass the following keyword arguments to the loader on initialisation:
loader_func Function that takes the name of the template to load. If it returns a string or unicode object it's used to load a template. If the return value is None it's considered missing. getmtime_func Function used to check if templates requires reloading. Has to return the UNIX timestamp of the last template change or -1 if this template does not exist or requires updates at any cost. use_memcache Set this to True to enable memory caching. This is usually a good idea in production mode, but disable it during development since it won't reload template changes automatically. This only works in persistent environments like FastCGI. memcache_size Number of template instance you want to cache. Defaults to 40. cache_folder Set this to an existing directory to enable caching of templates on the file system. Note that this only affects templates transformed into python code. Default is None which means that caching is disabled. auto_reload Set this to False for a slightly better performance. In that case of getmtime_func not being provided this won't have an effect. - PackageLoader
Loads templates from python packages using setuptools.
from jinja import Environment, PackageLoader e = Environment(loader=PackageLoader('yourapp', 'template/path'))
You can pass the following keyword arguments to the loader on initialisation:
package_name Name of the package containing the templates. package_path Path of the templates inside the package. use_memcache Set this to True to enable memory caching. This is usually a good idea in production mode, but disable it during development since it won't reload template changes automatically. This only works in persistent environments like FastCGI. memcache_size Number of template instance you want to cache. Defaults to 40. cache_folder Set this to an existing directory to enable caching of templates on the file system. Note that this only affects templates transformed into python code. Default is None which means that caching is disabled. auto_reload Set this to False for a slightly better performance. In that case Jinja won't check for template changes on the filesystem. If the templates are inside of an egg file this won't have an effect.
Developing Loaders
Template loaders are just normal Python classes that have to provide some functions used to load and translate templates. Because some of the tasks a loader has to do are redundant there are some classes that make loader development easier.
Here the implementation of a simple loader based on the BaseLoader from jinja.loaders:
import codecs from os.path import join from jinja.loaders import BaseLoader from jinja.exceptions import TemplateNotFound class SimpleLoader(BaseLoader): def __init__(self, path): self.path = path def get_source(self, environment, name, parent): filename = join(self.path, name) if not path.exists(filename): raise TemplateNotFound(name) f = codecs.open(filename, 'r', environment.template_charset) try: return f.read() finally: f.close()
The functions load and parse which are a requirement for a loader are added automatically by the BaseLoader.
Additionally to the BaseLoader there is a mixin class called CachedLoaderMixin that implements memory and disk caching of templates. Note that you have to give it a higher priority in the MRO than the BaseLoader which means that's the first base class when inheriting from it:
import codecs from os.path import join, getmtime, exists from jinja.loaders import BaseLoaderCachedLoaderMixin from jinja.exceptions import TemplateNotFound class CachedLoader(CachedLoaderMixin, BaseLoader): def __init__(self, path): self.path = path CachedLoaderMixin.__init__( True, # use memory caching 40, # for up to 40 templates '/tmp', # additionally save the compiled templates in /tmp True # and reload cached templates automatically if changed ) def get_source(self, environment, name, parent): filename = join(self.path, name) if not path.exists(filename): raise TemplateNotFound(name) f = codecs.open(filename, 'r', environment.template_charset) try: return f.read() finally: f.close() def check_source_changed(self, environment, name): fn = join(self.path, name) if exists(fn): return getmtime(fn) return -1
You don't have to provide the check_source_changed method. If it doesn't exist the option auto_reload won't have an effect. Also note that the check_source_changed method must not raise an exception if the template does not exist but return -1. The return value -1 is considered "always reload" whereas 0 means "do not reload".