Mercurial > genshi > mirror
changeset 439:9f11c745fac9 trunk
Add support for adding custom template filters by passing a custom callback function to the `TemplateLoader`. Closes #89 (see added unit test).
author | cmlenz |
---|---|
date | Mon, 02 Apr 2007 19:43:31 +0000 |
parents | 2c38ec4e2dff |
children | 7884617bc941 |
files | genshi/filters.py genshi/template/loader.py genshi/template/tests/loader.py |
diffstat | 3 files changed, 46 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/genshi/filters.py +++ b/genshi/filters.py @@ -62,11 +62,10 @@ data = {} self.data = data - def __call__(self, stream, ctxt=None): + def __call__(self, stream): """Apply the filter to the given stream. :param stream: the markup event stream to filter - :param ctxt: the template context (unused) """ in_form = in_select = in_option = in_textarea = False select_value = option_value = textarea_value = None @@ -251,11 +250,10 @@ self.uri_attrs = uri_attrs self.safe_schemes = safe_schemes - def __call__(self, stream, ctxt=None): + def __call__(self, stream): """Apply the filter to the given stream. :param stream: the markup event stream to filter - :param ctxt: the template context (unused) """ waiting_for = None
--- a/genshi/template/loader.py +++ b/genshi/template/loader.py @@ -72,7 +72,8 @@ >>> os.remove(path) """ def __init__(self, search_path=None, auto_reload=False, - default_encoding=None, max_cache_size=25, default_class=None): + default_encoding=None, max_cache_size=25, default_class=None, + callback=None): """Create the template laoder. :param search_path: a list of absolute path names that should be @@ -86,6 +87,11 @@ cache :param default_class: the default `Template` subclass to use when instantiating templates + :param callback: (optional) a callback function that is invoked after a + template was initialized by this loader; the function + is passed the template object as only argument. This + callback can be used for example to add any desired + filters to the template """ from genshi.template.markup import MarkupTemplate @@ -97,6 +103,9 @@ self.auto_reload = auto_reload self.default_encoding = default_encoding self.default_class = default_class or MarkupTemplate + if callback is not None and not callable(callback): + raise TypeError('The "callback" parameter needs to be callable') + self.callback = callback self._cache = LRUCache(max_cache_size) self._mtime = {} self._lock = threading.Lock() @@ -186,10 +195,12 @@ dirname = '' tmpl = cls(fileobj, basedir=dirname, filename=filename, loader=self, encoding=encoding) + if self.callback: + self.callback(tmpl) + self._cache[filename] = tmpl + self._mtime[filename] = os.path.getmtime(filepath) finally: fileobj.close() - self._cache[filename] = tmpl - self._mtime[filename] = os.path.getmtime(filepath) return tmpl except IOError: continue
--- a/genshi/template/tests/loader.py +++ b/genshi/template/tests/loader.py @@ -17,6 +17,7 @@ import tempfile import unittest +from genshi.core import TEXT from genshi.template.loader import TemplateLoader from genshi.template.markup import MarkupTemplate @@ -189,6 +190,35 @@ loader = TemplateLoader([self.dirname], default_encoding='utf-8') loader.load('tmpl.html', encoding='iso-8859-1') + def test_load_with_callback(self): + fileobj = open(os.path.join(self.dirname, 'tmpl.html'), 'w') + try: + fileobj.write("""<html> + <p>Hello</p> + </html>""") + finally: + fileobj.close() + + def template_loaded(template): + def my_filter(stream, ctxt): + for kind, data, pos in stream: + if kind is TEXT and data.strip(): + data = ', '.join([data, data.lower()]) + yield kind, data, pos + template.filters.insert(0, my_filter) + + loader = TemplateLoader([self.dirname], callback=template_loaded) + tmpl = loader.load('tmpl.html') + self.assertEqual("""<html> + <p>Hello, hello</p> + </html>""", tmpl.generate().render()) + + # Make sure the filter is only added once + tmpl = loader.load('tmpl.html') + self.assertEqual("""<html> + <p>Hello, hello</p> + </html>""", tmpl.generate().render()) + def suite(): suite = unittest.TestSuite()