# HG changeset patch # User cmlenz # Date 1271365635 0 # Node ID 52d7d6b7b6c10fd11eb0142a97724decfde9bb1a # Parent b8ac236f025445f028b722db067c1413aa5a5a60 Templates instantiated without a loader now get an implicit loader based on their file path, or the current directory as a fallback. Closes #320. diff --git a/genshi/template/base.py b/genshi/template/base.py --- a/genshi/template/base.py +++ b/genshi/template/base.py @@ -395,6 +395,7 @@ self.lookup = lookup self.allow_exec = allow_exec self._init_filters() + self._init_loader() self._prepared = False if isinstance(source, basestring): @@ -419,9 +420,21 @@ return '<%s "%s">' % (type(self).__name__, self.filename) def _init_filters(self): - self.filters = [self._flatten] - if self.loader: - self.filters.append(self._include) + self.filters = [self._flatten, self._include] + + def _init_loader(self): + if self.loader is None: + from genshi.template.loader import TemplateLoader + if self.filename: + if self.filepath != self.filename: + basedir = os.path.normpath(self.filepath)[:-len( + os.path.normpath(self.filename)) + ] + else: + basedir = os.path.dirname(self.filename) + else: + basedir = '.' + self.loader = TemplateLoader([os.path.abspath(basedir)]) @property def stream(self): diff --git a/genshi/template/loader.py b/genshi/template/loader.py --- a/genshi/template/loader.py +++ b/genshi/template/loader.py @@ -131,6 +131,15 @@ self._uptodate = {} self._lock = threading.RLock() + def __getstate__(self): + state = self.__dict__.copy() + state['_lock'] = None + return state + + def __setstate__(self, state): + self.__dict__ = state + self._lock = threading.RLock() + def load(self, filename, relative_to=None, cls=None, encoding=None): """Load the template with the given name. diff --git a/genshi/template/markup.py b/genshi/template/markup.py --- a/genshi/template/markup.py +++ b/genshi/template/markup.py @@ -70,11 +70,8 @@ def _init_filters(self): Template._init_filters(self) # Make sure the include filter comes after the match filter - if self.loader: - self.filters.remove(self._include) - self.filters += [self._match] - if self.loader: - self.filters.append(self._include) + self.filters.remove(self._include) + self.filters += [self._match, self._include] def _parse(self, source, encoding): if not isinstance(source, Stream): 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 @@ -153,6 +153,50 @@
Included
""", tmpl.generate().render(encoding=None)) + def test_relative_include_without_loader(self): + file1 = open(os.path.join(self.dirname, 'tmpl1.html'), 'w') + try: + file1.write("""
Included
""") + finally: + file1.close() + + file2 = open(os.path.join(self.dirname, 'tmpl2.html'), 'w') + try: + file2.write(""" + + """) + finally: + file2.close() + + tmpl = MarkupTemplate(""" + + """, os.path.join(self.dirname, 'tmpl2.html'), 'tmpl2.html') + self.assertEqual(""" +
Included
+ """, tmpl.generate().render(encoding=None)) + + def test_relative_include_without_loader_relative(self): + file1 = open(os.path.join(self.dirname, 'tmpl1.html'), 'w') + try: + file1.write("""
Included
""") + finally: + file1.close() + + file2 = open(os.path.join(self.dirname, 'tmpl2.html'), 'w') + try: + file2.write(""" + + """) + finally: + file2.close() + + tmpl = MarkupTemplate(""" + + """, filename=os.path.join(self.dirname, 'tmpl2.html')) + self.assertEqual(""" +
Included
+ """, tmpl.generate().render(encoding=None)) + def test_relative_include_without_search_path_nested(self): file1 = open(os.path.join(self.dirname, 'tmpl1.html'), 'w') try: