# HG changeset patch # User cmlenz # Date 1206629111 0 # Node ID 408ab81767c769c89a7adb82da709d3b135af0a3 # Parent 3d3c322ca97815276c10b3ae194c832e2045bb79 Fix for prefix-dispatched template loading. Closes #206. Thanks to Waldemar Kornewald for the patch. diff --git a/genshi/template/loader.py b/genshi/template/loader.py --- a/genshi/template/loader.py +++ b/genshi/template/loader.py @@ -202,7 +202,7 @@ for loadfunc in search_path: if isinstance(loadfunc, basestring): - loadfunc = TemplateLoader.directory(loadfunc) + loadfunc = directory(loadfunc) try: dirname, filename, fileobj, mtime = loadfunc(filename) except IOError: @@ -296,13 +296,13 @@ request to the delegate. >>> load = prefixed( - ... app1 = lambda filename: ('app1', filename), - ... app2 = lambda filename: ('app2', filename) + ... app1 = lambda filename: ('app1', filename, None, None), + ... app2 = lambda filename: ('app2', filename, None, None) ... ) >>> print load('app1/foo.html') - ('app1', 'foo.html') + ('', 'app1/foo.html', None, None) >>> print load('app2/bar.html') - ('app2', 'bar.html') + ('', 'app2/bar.html', None, None) :param delegates: mapping of path prefixes to loader functions :return: the loader function @@ -312,8 +312,12 @@ for prefix, delegate in delegates.items(): if filename.startswith(prefix): if isinstance(delegate, basestring): - delegate = TemplateLoader.directory(delegate) - return delegate(filename[len(prefix):].lstrip('/\\')) + delegate = directory(delegate) + path, _, fileobj, mtime = delegate( + filename[len(prefix):].lstrip('/\\') + ) + dirname = path[len(prefix):].rstrip('/\\') + return dirname, filename, fileobj, mtime raise TemplateNotFound(filename, delegates.keys()) return _dispatch_by_prefix prefixed = staticmethod(prefixed) diff --git a/genshi/template/tests/loader.py b/genshi/template/tests/loader.py --- a/genshi/template/tests/loader.py +++ b/genshi/template/tests/loader.py @@ -277,6 +277,16 @@ """, tmpl.generate().render()) def test_prefix_delegation_to_directories(self): + """ + Test prefix delegation with the following layout: + + templates/foo.html + sub1/templates/tmpl1.html + sub2/templates/tmpl2.html + + Where sub1 and sub2 are prefixes, and both tmpl1.html and tmpl2.html + incldue foo.html. + """ dir1 = os.path.join(self.dirname, 'templates') os.mkdir(dir1) file1 = open(os.path.join(dir1, 'foo.html'), 'w') @@ -290,7 +300,7 @@ file2 = open(os.path.join(dir2, 'tmpl1.html'), 'w') try: file2.write(""" - from sub1 + from sub1 """) finally: file2.close() @@ -299,9 +309,7 @@ os.makedirs(dir3) file3 = open(os.path.join(dir3, 'tmpl2.html'), 'w') try: - file3.write(""" - from sub2 - """) + file3.write("""
tmpl2
""") finally: file3.close() @@ -314,6 +322,62 @@
Included foo
from sub1 """, tmpl.generate().render()) + def test_prefix_delegation_to_directories_with_subdirs(self): + """ + Test prefix delegation with the following layout: + + templates/foo.html + sub1/templates/tmpl1.html + sub1/templates/tmpl2.html + sub1/templates/bar/tmpl3.html + + Where sub1 is a prefix, and tmpl1.html includes all the others. + """ + dir1 = os.path.join(self.dirname, 'templates') + os.mkdir(dir1) + file1 = open(os.path.join(dir1, 'foo.html'), 'w') + try: + file1.write("""
Included foo
""") + finally: + file1.close() + + dir2 = os.path.join(self.dirname, 'sub1', 'templates') + os.makedirs(dir2) + file2 = open(os.path.join(dir2, 'tmpl1.html'), 'w') + try: + file2.write(""" + from sub1 + from sub1 + from sub1 + """) + finally: + file2.close() + + file3 = open(os.path.join(dir2, 'tmpl2.html'), 'w') + try: + file3.write("""
tmpl2
""") + finally: + file3.close() + + dir3 = os.path.join(self.dirname, 'sub1', 'templates', 'bar') + os.makedirs(dir3) + file4 = open(os.path.join(dir3, 'tmpl3.html'), 'w') + try: + file4.write("""
bar/tmpl3
""") + finally: + file4.close() + + loader = TemplateLoader([dir1, TemplateLoader.prefixed( + sub1 = os.path.join(dir2), + sub2 = os.path.join(dir3) + )]) + tmpl = loader.load('sub1/tmpl1.html') + self.assertEqual(""" +
Included foo
from sub1 +
tmpl2
from sub1 +
bar/tmpl3
from sub1 + """, tmpl.generate().render()) + def suite(): suite = unittest.TestSuite()