.. sourcecode:: python
import codecs
- from os.path import join, getmtime
+ from os.path import join, getmtime, exists
from jinja.loaders import BaseLoaderCachedLoaderMixin
from jinja.exceptions import TemplateNotFound
f.close()
def check_source_changed(self, environment, name):
- return getmtime(join(self.path, name))
+ fn = join(self.path, name)
+ if exists(fn):
+ return getmtime(fn)
+ return 0
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.
+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 ``0``.
resource_exists = resource_string = resource_filename = None
-__all__ = ['FileSystemLoader', 'PackageLoader', 'DictLoader']
+__all__ = ['FileSystemLoader', 'PackageLoader', 'DictLoader', 'ChoiceLoader']
def get_template_filename(searchpath, name):
raise TemplateNotFound(name)
def check_source_changed(self, environment, name):
- return path.getmtime(get_template_filename(self.searchpath, name))
+ filename = get_template_filename(self.searchpath, name)
+ if path.exists(filename):
+ return path.getmtime(filename)
+ return 0
class PackageLoader(CachedLoaderMixin, BaseLoader):
return contents.decode(environment.template_charset)
def check_source_changed(self, environment, name):
- name = '/'.join([self.package_path] + [p for p in name.split('/')
- if p and p[0] != '.'])
- return path.getmtime(resource_filename(self.package_name, name))
+ fn = resource_filename(self.package_name, '/'.join([self.package_path] +
+ [p for p in name.split('/') if p and p[0] != '.']))
+ if resource_exists(self.package_name, fn):
+ return path.getmtime(fn)
+ return 0
class DictLoader(BaseLoader):
from jinja import Environment, DictLoader
e = Environment(loader=DictLoader(dict(
layout='...',
- index='{% extends layout %}...'
+ index='{% extends 'layout' %}...'
)))
"""
if name in self.templates:
return self.templates[name]
raise TemplateNotFound(name)
+
+
+class ChoiceLoader(object):
+ """
+ A loader that tries multiple loaders in the order they are given to
+ the `ChoiceLoader`:
+
+ .. sourcecode:: python
+
+ from jinja import ChoiceLoader, FileSystemLoader
+ loader1 = FileSystemLoader("templates1")
+ loader2 = FileSystemLoader("templates2")
+ loader = ChoiceLoader([loader1, loader2])
+ """
+
+ def __init__(self, loaders):
+ self.loaders = list(loaders)
+
+ def get_source(self, environment, name, parent):
+ for loader in self.loaders:
+ try:
+ return loader.get_source(environment, name, parent)
+ except TemplateNotFound:
+ continue
+ raise TemplateNotFound(name)
+
+ def parse(self, environment, name, parent):
+ for loader in self.loaders:
+ try:
+ return loader.parse(environment, name, parent)
+ except TemplateNotFound:
+ continue
+ raise TemplateNotFound(name)
+
+ def load(self, environment, name, translator):
+ for loader in self.loaders:
+ try:
+ return loader.load(environment, name, translator)
+ except TemplateNotFound:
+ continue
+ raise TemplateNotFound(name)
--- /dev/null
+# -*- coding: utf-8 -*-
+"""
+ unit test for the loaders
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ :copyright: 2007 by Armin Ronacher.
+ :license: BSD, see LICENSE for more details.
+"""
+
+from jinja import Environment, loaders
+from jinja.exceptions import TemplateNotFound
+
+
+dict_loader = loaders.DictLoader({
+ 'justdict.html': 'FOO'
+})
+
+package_loader = loaders.PackageLoader('loaderres', 'templates')
+
+filesystem_loader = loaders.FileSystemLoader('loaderres/templates')
+
+choice_loader = loaders.ChoiceLoader([dict_loader, package_loader])
+
+
+def test_dict_loader():
+ env = Environment(loader=dict_loader)
+ tmpl = env.get_template('justdict.html')
+ assert tmpl.render().strip() == 'FOO'
+ try:
+ env.get_template('missing.html')
+ except TemplateNotFound:
+ pass
+ else:
+ raise AssertionError('expected template exception')
+
+
+def test_package_loader():
+ env = Environment(loader=package_loader)
+ tmpl = env.get_template('test.html')
+ assert tmpl.render().strip() == 'BAR'
+ try:
+ env.get_template('missing.html')
+ except TemplateNotFound:
+ pass
+ else:
+ raise AssertionError('expected template exception')
+
+
+def test_filesystem_loader():
+ env = Environment(loader=filesystem_loader)
+ tmpl = env.get_template('test.html')
+ assert tmpl.render().strip() == 'BAR'
+ try:
+ env.get_template('missing.html')
+ except TemplateNotFound:
+ pass
+ else:
+ raise AssertionError('expected template exception')
+
+
+def test_choice_loader():
+ env = Environment(loader=choice_loader)
+ tmpl = env.get_template('justdict.html')
+ assert tmpl.render().strip() == 'FOO'
+ tmpl = env.get_template('test.html')
+ assert tmpl.render().strip() == 'BAR'
+ try:
+ env.get_template('missing.html')
+ except TemplateNotFound:
+ pass
+ else:
+ raise AssertionError('expected template exception')
--- /dev/null
+# -*- coding: utf-8 -*-
+"""
+ unit test for various things
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ :copyright: 2007 by Armin Ronacher.
+ :license: BSD, see LICENSE for more details.
+"""
+
+KEYWORDS = '''
+{{ with }}
+{{ as }}
+{{ import }}
+{{ from }}
+{{ class }}
+{{ def }}
+{{ try }}
+{{ except }}
+{{ exec }}
+{{ global }}
+{{ assert }}
+{{ break }}
+{{ continue }}
+{{ lambda }}
+{{ return }}
+{{ raise }}
+{{ yield }}
+{{ while }}
+{{ pass }}
+{{ finally }}
+'''
+
+UNPACKING = '''{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor %}'''
+
+RAW = '''{% raw %}{{ FOO }} and {% BAR %}{% endraw %}'''
+
+
+def test_keywords(env):
+ env.from_string(KEYWORDS)
+
+
+def test_unpacking(env):
+ tmpl = env.from_string(UNPACKING)
+ assert tmpl.render() == '1|2|3'
+
+
+def test_raw(env):
+ tmpl = env.from_string(RAW)
+ assert tmpl.render() == '{{ FOO }} and {% BAR %}'
+
+
+def test_cache_dict():
+ from jinja.utils import CacheDict
+ d = CacheDict(3)
+ d["a"] = 1
+ d["b"] = 2
+ d["c"] = 3
+ d["a"]
+ d["d"] = 4
+ assert len(d) == 3
+ assert 'a' in d and 'c' in d and 'd' in d and 'b' not in d