Skip to content

Commit

Permalink
Improved choice and prefix loaders.
Browse files Browse the repository at this point in the history
Choice and prefix loaders now dispatch source and template lookup
separately in order to work in combination with module loaders as
advertised.
  • Loading branch information
mitsuhiko committed Sep 13, 2011
1 parent 9b1de00 commit 6fa6cb0
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
8 changes: 8 additions & 0 deletions CHANGES
@@ -1,6 +1,14 @@
Jinja2 Changelog
================

Version 2.7
-----------
(codename to be selected, release date to be announced)

- Choice and prefix loaders now dispatch source and template lookup
separately in order to work in combination with module loaders as
advertised.

Version 2.6
-----------
(codename Convolution, released on July 24th 2011)
Expand Down
25 changes: 24 additions & 1 deletion jinja2/loaders.py
Expand Up @@ -330,19 +330,33 @@ def __init__(self, mapping, delimiter='/'):
self.mapping = mapping
self.delimiter = delimiter

def get_source(self, environment, template):
def get_loader(self, template):
try:
prefix, name = template.split(self.delimiter, 1)
loader = self.mapping[prefix]
except (ValueError, KeyError):
raise TemplateNotFound(template)
return loader, name

def get_source(self, environment, template):
loader, name = self.get_loader(template)
try:
return loader.get_source(environment, name)
except TemplateNotFound:
# re-raise the exception with the correct fileame here.
# (the one that includes the prefix)
raise TemplateNotFound(template)

@internalcode
def load(self, environment, name, globals=None):
loader, local_name = self.get_loader(name)
try:
return loader.load(environment, local_name)
except TemplateNotFound:
# re-raise the exception with the correct fileame here.
# (the one that includes the prefix)
raise TemplateNotFound(name)

def list_templates(self):
result = []
for prefix, loader in self.mapping.iteritems():
Expand Down Expand Up @@ -376,6 +390,15 @@ def get_source(self, environment, template):
pass
raise TemplateNotFound(template)

@internalcode
def load(self, environment, name, globals=None):
for loader in self.loaders:
try:
return loader.load(environment, name, globals)
except TemplateNotFound:
pass
raise TemplateNotFound(name)

def list_templates(self):
found = set()
for loader in self.loaders:
Expand Down
28 changes: 28 additions & 0 deletions jinja2/testsuite/loader.py
Expand Up @@ -182,6 +182,34 @@ def test_byte_compilation(self):
tmpl_3c4ddf650c1a73df961a6d3d2ce2752f1b8fd490
assert mod.__file__.endswith('.pyc')

def test_choice_loader(self):
log = self.compile_down(py_compile=True)
assert 'Byte-compiled "a/test.html"' in log

self.mod_env.loader = loaders.ChoiceLoader([
self.mod_env.loader,
loaders.DictLoader({'DICT_SOURCE': 'DICT_TEMPLATE'})
])

tmpl1 = self.mod_env.get_template('a/test.html')
self.assert_equal(tmpl1.render(), 'BAR')
tmpl2 = self.mod_env.get_template('DICT_SOURCE')
self.assert_equal(tmpl2.render(), 'DICT_TEMPLATE')

def test_prefix_loader(self):
log = self.compile_down(py_compile=True)
assert 'Byte-compiled "a/test.html"' in log

self.mod_env.loader = loaders.PrefixLoader({
'MOD': self.mod_env.loader,
'DICT': loaders.DictLoader({'test.html': 'DICT_TEMPLATE'})
})

tmpl1 = self.mod_env.get_template('MOD/a/test.html')
self.assert_equal(tmpl1.render(), 'BAR')
tmpl2 = self.mod_env.get_template('DICT/test.html')
self.assert_equal(tmpl2.render(), 'DICT_TEMPLATE')


def suite():
suite = unittest.TestSuite()
Expand Down

0 comments on commit 6fa6cb0

Please sign in to comment.