Mercurial > genshi > genshi-test
changeset 104:e9259920db05
Added `py:with` directive based on Jonas' patch in #17.
author | cmlenz |
---|---|
date | Thu, 27 Jul 2006 09:22:17 +0000 |
parents | 70ec95c8d1ea |
children | 334a338847af |
files | markup/template.py markup/tests/template.py |
diffstat | 2 files changed, 67 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/markup/template.py +++ b/markup/template.py @@ -619,6 +619,47 @@ return _apply_directives(stream, ctxt, directives) +class WithDirective(Directive): + """Implementation of the `py:with` template directive, which allows + shorthand access to variables and expressions. + + >>> tmpl = Template('''<div xmlns:py="http://markup.edgewall.org/"> + ... <span py:with="y=7; z=x+10">$x $y $z</span> + ... </div>''') + >>> print tmpl.generate(Context(x=42)) + <div> + <span>42 7 52</span> + </div> + """ + __slots__ = ['vars'] + + ATTRIBUTE = 'vars' + + def __init__(self, value, filename=None, lineno=-1, offset=-1): + Directive.__init__(self, None, filename, lineno, offset) + self.vars = [] + try: + for stmt in value.split(';'): + name, value = stmt.split('=', 1) + self.vars.append((name.strip(), + Expression(value.strip(), filename, lineno))) + except SyntaxError, err: + raise TemplateSyntaxError(err, filename, lineno, + offset + (err.offset or 0)) + + def __call__(self, stream, ctxt, directives): + ctxt.push(dict([(name, expr.evaluate(ctxt)) + for name, expr in self.vars])) + for event in _apply_directives(stream, ctxt, directives): + yield event + ctxt.pop() + + def __repr__(self): + return '<%s "%s">' % (self.__class__.__name__, + '; '.join(['%s = %s' % (name, expr.source) + for name, expr in self.vars])) + + class Template(object): """Can parse a template and transform it into the corresponding output based on context data. @@ -635,6 +676,7 @@ ('when', WhenDirective), ('otherwise', OtherwiseDirective), ('choose', ChooseDirective), + ('with', WithDirective), ('replace', ReplaceDirective), ('content', ContentDirective), ('attrs', AttrsDirective),
--- a/markup/tests/template.py +++ b/markup/tests/template.py @@ -414,6 +414,30 @@ </div>""", str(tmpl.generate())) +class WithDirectiveTestCase(unittest.TestCase): + """Tests for the `py:with` template directive.""" + + def test_shadowing(self): + tmpl = Template("""<div xmlns:py="http://markup.edgewall.org/"> + ${x} + <span py:with="x = x * 2" py:replace="x"/> + ${x} + </div>""") + self.assertEqual("""<div> + 42 + 84 + 42 + </div>""", str(tmpl.generate(Context(x=42)))) + + def test_as_element(self): + tmpl = Template("""<div xmlns:py="http://markup.edgewall.org/"> + <py:with vars="x = x * 2">${x}</py:with> + </div>""") + self.assertEqual("""<div> + 84 + </div>""", str(tmpl.generate(Context(x=42)))) + + class TemplateTestCase(unittest.TestCase): """Tests for basic template processing, expression evaluation and error reporting. @@ -578,6 +602,7 @@ suite.addTest(unittest.makeSuite(IfDirectiveTestCase, 'test')) suite.addTest(unittest.makeSuite(MatchDirectiveTestCase, 'test')) suite.addTest(unittest.makeSuite(StripDirectiveTestCase, 'test')) + suite.addTest(unittest.makeSuite(WithDirectiveTestCase, 'test')) return suite if __name__ == '__main__':