- fixed cache code to work with Beaker 1.0.1, which is now the required version of Beaker. - removed unnecessary attributes from DefTemplate. - added ModuleTemplate class, which allows the construction of a Template given a Python module generated by a previous Template. This allows Python modules alone to be used as templates with no compilation step. Source code and template source are optional but allow error reporting to work correctly.
diff --git a/CHANGES b/CHANGES index a559672..dc271cc 100644 --- a/CHANGES +++ b/CHANGES
@@ -4,10 +4,19 @@ "ext:google", "ext:sqla", etc. are available. memcached is available as both "ext:memcached" and "memcached", the latter for backwards compatibility. +This requires Beaker>=1.0.1. - fixed the html_error_template not handling tracebacks from normal .py files with a magic encoding comment [ticket:88] +- added ModuleTemplate class, which allows the construction +of a Template given a Python module generated by a previous +Template. This allows Python modules alone to be used +as templates with no compilation step. Source code +and template source are optional but allow error reporting +to work correctly. + + 0.2.2 - cached blocks now use the current context when rendering an expired section, instead of the original context
diff --git a/doc/build/genhtml.py b/doc/build/genhtml.py index cdef146..59eb6eb 100644 --- a/doc/build/genhtml.py +++ b/doc/build/genhtml.py
@@ -24,7 +24,7 @@ ] title='Mako Documentation' -version = '0.2.2' +version = '0.2.3' root = toc.TOCElement('', 'root', '', version=version, doctitle=title)
diff --git a/lib/mako/cache.py b/lib/mako/cache.py index 3332585..457b966 100644 --- a/lib/mako/cache.py +++ b/lib/mako/cache.py
@@ -27,5 +27,6 @@ raise exceptions.RuntimeException("the Beaker package is required to use cache functionality.") kw = self.kwargs.copy() kw.update(kwargs) - return clsmap[type](key, self.context, self.id, starttime=self.starttime, **kw) + + return container.Value(key, self.context, self.id, clsmap[type], starttime=self.starttime, **kw)
diff --git a/lib/mako/template.py b/lib/mako/template.py index b1441a4..f7d7fef 100644 --- a/lib/mako/template.py +++ b/lib/mako/template.py
@@ -107,9 +107,16 @@ self.cache_dir = cache_dir self.cache_url = cache_url - source = property(lambda self:_get_module_info_from_callable(self.callable_).source, doc="""return the template source code for this Template.""") - code = property(lambda self:_get_module_info_from_callable(self.callable_).code, doc="""return the module source code for this Template""") - + def source(self): + """return the template source code for this Template.""" + return _get_module_info_from_callable(self.callable_).source + source = property(source) + + def code(self): + """return the module source code for this Template""" + return _get_module_info_from_callable(self.callable_).code + code = property(code) + def render(self, *args, **data): """render the output of this template as a string. @@ -139,27 +146,60 @@ def get_def(self, name): """return a def of this template as an individual Template of its own.""" return DefTemplate(self, getattr(self.module, "render_%s" % name)) + + +class ModuleTemplate(Template): + """A Template which is constructed given an existing Python module. + + e.g.:: + t = Template("this is a template") + f = file("mymodule.py") + f.write(t.code) + f.close() + + import mymodule + + t = ModuleTemplate(mymodule) + print t.render() + + """ + + def __init__(self, module, + module_filename=None, + template=None, template_filename=None, + module_source=None, template_source=None, + output_encoding=None, encoding_errors='strict', disable_unicode=False, format_exceptions=False, + error_handler=None, lookup=None, cache_type=None, cache_dir=None, cache_url=None + ): + self.module_id = re.sub(r'\W', "_", module._template_uri) + self.uri = module._template_uri + self.input_encoding = module._source_encoding + self.output_encoding = output_encoding + self.encoding_errors = encoding_errors + self.disable_unicode = disable_unicode + self.module = module + self.filename = template_filename + ModuleInfo(module, module_filename, self, template_filename, module_source, template_source) + + self.callable_ = self.module.render_body + self.format_exceptions = format_exceptions + self.error_handler = error_handler + self.lookup = lookup + self.cache_type = cache_type + self.cache_dir = cache_dir + self.cache_url = cache_url + class DefTemplate(Template): """a Template which represents a callable def in a parent template.""" def __init__(self, parent, callable_): self.parent = parent self.callable_ = callable_ - self.default_filters = parent.default_filters - self.buffer_filters = parent.buffer_filters - self.input_encoding = parent.input_encoding - self.imports = parent.imports - self.disable_unicode = parent.disable_unicode self.output_encoding = parent.output_encoding self.encoding_errors = parent.encoding_errors self.format_exceptions = parent.format_exceptions self.error_handler = parent.error_handler self.lookup = parent.lookup - self.module = parent.module - self.filename = parent.filename - self.cache_type = parent.cache_type - self.cache_dir = parent.cache_dir - self.cache_url = parent.cache_url def get_def(self, name): return self.parent.get_def(name)
diff --git a/setup.py b/setup.py index eb42a22..5cd2558 100644 --- a/setup.py +++ b/setup.py
@@ -37,7 +37,7 @@ scripts=['scripts/mako-render'], zip_safe=False, install_requires=[ - 'Beaker', + 'Beaker>=1.0.1', ], entry_points=""" [python.templating.engines]
diff --git a/test/def.py b/test/def.py index 38c6f00..4bc5563 100644 --- a/test/def.py +++ b/test/def.py
@@ -74,7 +74,7 @@ this is b, ${x} ${y} </%def> - """) + """, output_encoding='utf-8') assert flatten_result(template.get_def("a").render()) == "this is a" assert flatten_result(template.get_def("b").render(x=10, y=15)) == "this is b, 10 15" assert flatten_result(template.get_def("body").render()) == "this is the body"
diff --git a/test/template.py b/test/template.py index 1727f35..ab535d8 100644 --- a/test/template.py +++ b/test/template.py
@@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from mako.template import Template +from mako.template import Template, ModuleTemplate from mako.lookup import TemplateLookup from mako.ext.preprocessors import convert_comments from mako import exceptions @@ -391,6 +391,42 @@ assert t.module.__file__ == 'test_htdocs/foo/modtest.html.py' assert t2.module.__file__ == 'test_htdocs/subdir/foo/modtest.html.py' +class ModuleTemplateTest(unittest.TestCase): + def test_module_roundtrip(self): + lookup = TemplateLookup() + + template = Template(""" + <%inherit file="base.html"/> + + % for x in range(5): + ${x} + % endfor +""", lookup=lookup) + + base = Template(""" + This is base. + ${self.body()} +""", lookup=lookup) + + lookup.put_template("base.html", base) + lookup.put_template("template.html", template) + + assert result_lines(template.render()) == [ + "This is base.", "0", "1", "2", "3", "4" + ] + + lookup = TemplateLookup() + template = ModuleTemplate(template.module, lookup=lookup) + base = ModuleTemplate(base.module, lookup=lookup) + + lookup.put_template("base.html", base) + lookup.put_template("template.html", template) + + assert result_lines(template.render()) == [ + "This is base.", "0", "1", "2", "3", "4" + ] + + class PreprocessTest(unittest.TestCase): def test_old_comments(self): t = Template("""