==================
Template loaders are just normal Python classes that have to provide some
-functions used to load and translate templates.
+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.
-Because some of the tasks a loader has to do are redundant there are mixin
-classes that make loader development easier.
-
-Here the implementation of a simple loader based on the `LoaderMixin` from
+Here the implementation of a simple loader based on the `BaseLoader` from
`jinja.loaders`:
.. sourcecode:: python
import codecs
from os.path import join
- from jinja.loaders import LoaderMixin
+ from jinja.loaders import BaseLoader
from jinja.exceptions import TemplateNotFound
- class SimpleLoader(LoaderMixin):
+ class SimpleLoader(BaseLoader):
def __init__(self, path):
self.path = path
f.close()
The functions `load` and `parse` which are a requirement for a loader are
-added automatically by the `LoaderMixin`.
+added automatically by the `BaseLoader`.
-Additionally to the `LoaderMixin` there is a second mixin called
+Additionally to the `BaseLoader` there is a mixin class called
`CachedLoaderMixin` that implements memory and disk caching of templates.
-
-It works basically the same, just that there are two more things to implement:
+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:
.. sourcecode:: python
import codecs
from os.path import join, getmtime
- from jinja.loaders import CachedLoaderMixin
+ from jinja.loaders import BaseLoaderCachedLoaderMixin
from jinja.exceptions import TemplateNotFound
- class CachedLoader(CachedLoaderMixin):
+ class CachedLoader(CachedLoaderMixin, BaseLoader):
def __init__(self, path):
self.path = path
return self.loader is not None
-class LoaderMixin(object):
+class BaseLoader(object):
"""
Use this class to implement loaders.
- Just mixin this class and implement a method called `get_source`
- with the signature (`environment`, `name`, `parent`) that returns
- sourcecode for the template.
+ Just inherit from this class and implement a method called
+ `get_source` with the signature (`environment`, `name`, `parent`)
+ that returns sourcecode for the template.
For more complex loaders you probably want to override `load` to
- or not use the `LoaderMixin` at all.
+ or not use the `BaseLoader` at all.
"""
def parse(self, environment, name, parent):
return translator.process(environment, ast)
-class CachedLoaderMixin(LoaderMixin):
+class CachedLoaderMixin(object):
"""
- Works like the loader mixin just that it supports caching.
+ Mixin this class to implement simple memory and disk caching.
"""
def __init__(self, use_memcache, cache_size, cache_folder, auto_reload):
self.__lock = Lock()
def load(self, environment, name, translator):
+ """
+ Load and translate a template. First we check if there is a
+ cached version of this template in the memory cache. If this is
+ not the cache check for a compiled template in the disk cache
+ folder. And if none of this is the case we translate the temlate
+ using the `LoaderMixin.load` function, cache and return it.
+ """
self.__lock.acquire()
try:
# caching is only possible for the python translator. skip
# no template so far, parse, translate and compile it
elif tmpl is None:
- tmpl = LoaderMixin.load(self, environment,
- name, translator)
+ tmpl = super(CachedLoaderMixin, self).load(
+ environment, name, translator)
# save the compiled template
f = file(cache_fn, 'wb')
# if we reach this point we don't have caching enabled or translate
# to something else than python
- return LoaderMixin.load(self, environment, name, translator)
+ return super(CachedLoaderMixin, self).load(
+ environment, name, translator)
finally:
self.__lock.release()
-class FileSystemLoader(CachedLoaderMixin):
+class FileSystemLoader(CachedLoaderMixin, BaseLoader):
"""
Loads templates from the filesystem:
return path.getmtime(get_template_filename(self.searchpath, name))
-class PackageLoader(CachedLoaderMixin):
+class PackageLoader(CachedLoaderMixin, BaseLoader):
"""
Loads templates from python packages using setuptools.
name = '/'.join([self.package_path] + [p for p in name.split('/')
if p and p[0] != '.'])
return path.getmtime(resource_filename(name))
+
+
+class DictLoader(BaseLoader):
+ """
+ Load templates from a given dict:
+
+ .. sourcecode:: python
+
+ from jinja import Environment, DictLoader
+ e = Environment(loader=DictLoader(dict(
+ layout='...',
+ index='{% extends layout %}...'
+ )))
+ """
+
+ def __init__(self, templates):
+ self.templates = templates
+
+ def get_source(self, environment, name, parent):
+ if name in self.templates:
+ return self.templates[name]
+ raise TemplateNotFound(name)