Mercurial > genshi > genshi-test
changeset 149:7306bf730ff3
`Template.generate()` now accepts the context data as keyword arguments, so that you don't have to import the `Context` class every time you want to pass data into a template.
author | cmlenz |
---|---|
date | Tue, 15 Aug 2006 21:59:07 +0000 |
parents | a0a52cf4e4de |
children | 39a8012f60e3 |
files | COPYING examples/basic/run.py examples/bench/basic.py examples/bench/bigtable.py markup/plugin.py markup/template.py markup/tests/template.py |
diffstat | 7 files changed, 53 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 2006 Christopher Lenz +Copyright (C) 2006 Edgewall Software All rights reserved. Redistribution and use in source and binary forms, with or without
--- a/examples/basic/run.py +++ b/examples/basic/run.py @@ -5,7 +5,7 @@ import sys import time -from markup.template import Context, TemplateLoader +from markup.template import TemplateLoader def test(): base_path = os.path.dirname(os.path.abspath(__file__)) @@ -19,12 +19,12 @@ items=['Number %d' % num for num in range(1, 15)], prefix='#') - print tmpl.generate(Context(**data)).render(method='html') + print tmpl.generate(**data).render(method='html') times = [] for i in range(1000): start = time.clock() - list(tmpl.generate(Context(**data))) + list(tmpl.generate(**data)) times.append(time.clock() - start) sys.stdout.write('.') sys.stdout.flush()
--- a/examples/bench/basic.py +++ b/examples/bench/basic.py @@ -7,13 +7,13 @@ __all__ = ['clearsilver', 'django', 'kid', 'markup', 'simpletal'] def markup(dirname, verbose=False): - from markup.template import Context, TemplateLoader + from markup.template import TemplateLoader loader = TemplateLoader([dirname], auto_reload=False) template = loader.load('template.html') def render(): - ctxt = Context(title='Just a test', user='joe', - items=['Number %d' % num for num in range(1, 15)]) - return template.generate(ctxt).render('xhtml') + data = dict(title='Just a test', user='joe', + items=['Number %d' % num for num in range(1, 15)]) + return template.generate(**data).render('xhtml') if verbose: print render()
--- a/examples/bench/bigtable.py +++ b/examples/bench/bigtable.py @@ -12,7 +12,7 @@ import cElementTree as cet from elementtree import ElementTree as et from markup.builder import tag -from markup.template import Context, Template +from markup.template import Template import neo_cgi import neo_cs import neo_util @@ -66,8 +66,7 @@ def test_markup(): """Markup template""" - ctxt = Context(table=table) - stream = markup_tmpl.generate(ctxt) + stream = markup_tmpl.generate(table=table) stream.render('html', strip_whitespace=False) def test_markup_builder(): @@ -76,8 +75,7 @@ tag.tr([tag.td(c) for c in row.values()]) for row in table ]).generate() - ctxt = Context(table=stream) - stream = markup_tmpl2.generate(ctxt) + stream = markup_tmpl2.generate(table=stream) stream.render('html', strip_whitespace=False) def test_builder():
--- a/markup/plugin.py +++ b/markup/plugin.py @@ -75,5 +75,4 @@ data.update(self.get_extra_vars()) data.update(info) - ctxt = Context(**data) - return template.generate(ctxt) + return template.generate(**data)
--- a/markup/template.py +++ b/markup/template.py @@ -31,8 +31,7 @@ from markup.input import XMLParser from markup.path import Path -__all__ = ['Context', 'BadDirectiveError', 'TemplateError', - 'TemplateSyntaxError', 'TemplateNotFound', 'Template', +__all__ = ['TemplateSyntaxError', 'TemplateNotFound', 'Template', 'TemplateLoader'] @@ -178,11 +177,10 @@ The value of the `py:attrs` attribute should be a dictionary. The keys and values of that dictionary will be added as attributes to the element: - >>> ctxt = Context(foo={'class': 'collapse'}) >>> tmpl = Template('''<ul xmlns:py="http://markup.edgewall.org/"> ... <li py:attrs="foo">Bar</li> ... </ul>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(foo={'class': 'collapse'}) <ul> <li class="collapse">Bar</li> </ul> @@ -190,8 +188,7 @@ If the value evaluates to `None` (or any other non-truth value), no attributes are added: - >>> ctxt = Context(foo=None) - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(foo=None) <ul> <li>Bar</li> </ul> @@ -229,11 +226,10 @@ This directive replaces the content of the element with the result of evaluating the value of the `py:content` attribute: - >>> ctxt = Context(bar='Bye') >>> tmpl = Template('''<ul xmlns:py="http://markup.edgewall.org/"> ... <li py:content="bar">Hello</li> ... </ul>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(bar='Bye') <ul> <li>Bye</li> </ul> @@ -266,14 +262,13 @@ A named template function can be used just like a normal Python function from template expressions: - >>> ctxt = Context(bar='Bye') >>> tmpl = Template('''<div xmlns:py="http://markup.edgewall.org/"> ... <p py:def="echo(greeting, name='world')" class="message"> ... ${greeting}, ${name}! ... </p> ... ${echo('Hi', name='you')} ... </div>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(bar='Bye') <div> <p class="message"> Hi, you! @@ -283,14 +278,13 @@ If a function does not require parameters, the parenthesis can be omitted both when defining and when calling it: - >>> ctxt = Context(bar='Bye') >>> tmpl = Template('''<div xmlns:py="http://markup.edgewall.org/"> ... <p py:def="helloworld" class="message"> ... Hello, world! ... </p> ... ${helloworld} ... </div>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(bar='Bye') <div> <p class="message"> Hello, world! @@ -343,11 +337,10 @@ """Implementation of the `py:for` template directive for repeating an element based on an iterable in the context data. - >>> ctxt = Context(items=[1, 2, 3]) >>> tmpl = Template('''<ul xmlns:py="http://markup.edgewall.org/"> ... <li py:for="item in items">${item}</li> ... </ul>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(items=[1, 2, 3]) <ul> <li>1</li><li>2</li><li>3</li> </ul> @@ -390,11 +383,10 @@ """Implementation of the `py:if` template directive for conditionally excluding elements from being output. - >>> ctxt = Context(foo=True, bar='Hello') >>> tmpl = Template('''<div xmlns:py="http://markup.edgewall.org/"> ... <b py:if="foo">${bar}</b> ... </div>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(foo=True, bar='Hello') <div> <b>Hello</b> </div> @@ -450,11 +442,10 @@ This directive replaces the element with the result of evaluating the value of the `py:replace` attribute: - >>> ctxt = Context(bar='Bye') >>> tmpl = Template('''<div xmlns:py="http://markup.edgewall.org/"> ... <span py:replace="bar">Hello</span> ... </div>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(bar='Bye') <div> Bye </div> @@ -462,11 +453,10 @@ This directive is equivalent to `py:content` combined with `py:strip`, providing a less verbose way to achieve the same effect: - >>> ctxt = Context(bar='Bye') >>> tmpl = Template('''<div xmlns:py="http://markup.edgewall.org/"> ... <span py:content="bar" py:strip="">Hello</span> ... </div>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate(bar='Bye') <div> Bye </div> @@ -538,14 +528,13 @@ If no `py:when` directive is matched then the fallback directive `py:otherwise` will be used. - >>> ctxt = Context() >>> tmpl = Template('''<div xmlns:py="http://markup.edgewall.org/" ... py:choose=""> ... <span py:when="0 == 1">0</span> ... <span py:when="1 == 1">1</span> ... <span py:otherwise="">2</span> ... </div>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate() <div> <span>1</span> </div> @@ -558,7 +547,7 @@ ... <span py:when="1">1</span> ... <span py:when="2">2</span> ... </div>''') - >>> print tmpl.generate(ctxt) + >>> print tmpl.generate() <div> <span>2</span> </div> @@ -627,7 +616,7 @@ >>> 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)) + >>> print tmpl.generate(x=42) <div> <span>42 7 52</span> </div> @@ -839,16 +828,25 @@ return _interpolate(text, [cls._FULL_EXPR_RE, cls._SHORT_EXPR_RE]) _interpolate = classmethod(_interpolate) - def generate(self, ctxt=None): + def generate(self, *args, **kwargs): """Apply the template to the given context data. - @param ctxt: a `Context` instance containing the data for the template + Any keyword arguments are made available to the template as context + data. + + Only one positional argument is accepted: if it is provided, it must be + an instance of the `Context` class, and keyword arguments are ignored. + This calling style is used for internal processing. + @return: a markup event stream representing the result of applying the template to the context data. """ - if ctxt is None: - ctxt = Context() - if not hasattr(ctxt, '_match_templates'): + if args: + assert len(args) == 1 + ctxt = args[0] + assert isinstance(ctxt, Context) + else: + ctxt = Context(**kwargs) ctxt._match_templates = [] stream = self.stream
--- a/markup/tests/template.py +++ b/markup/tests/template.py @@ -16,8 +16,7 @@ import sys from markup.core import Markup, Stream -from markup.template import BadDirectiveError, Context, Template, \ - TemplateSyntaxError +from markup.template import BadDirectiveError, Template, TemplateSyntaxError class AttrsDirectiveTestCase(unittest.TestCase): @@ -33,7 +32,7 @@ items = [{'id': 1, 'class': 'foo'}, {'id': 2, 'class': 'bar'}] self.assertEqual("""<doc> <elem id="1" class="foo"/><elem id="2" class="bar"/> - </doc>""", str(tmpl.generate(Context(items=items)))) + </doc>""", str(tmpl.generate(items=items))) def test_update_existing_attr(self): """ @@ -202,7 +201,7 @@ <b>3</b> <b>4</b> <b>5</b> - </doc>""", str(tmpl.generate(Context(items=range(1, 6))))) + </doc>""", str(tmpl.generate(items=range(1, 6)))) def test_as_element(self): """ @@ -219,7 +218,7 @@ <b>3</b> <b>4</b> <b>5</b> - </doc>""", str(tmpl.generate(Context(items=range(1, 6))))) + </doc>""", str(tmpl.generate(items=range(1, 6)))) class IfDirectiveTestCase(unittest.TestCase): @@ -235,7 +234,7 @@ </doc>""") self.assertEqual("""<doc> Hello - </doc>""", str(tmpl.generate(Context(foo=True, bar='Hello')))) + </doc>""", str(tmpl.generate(foo=True, bar='Hello'))) def test_as_element(self): """ @@ -246,7 +245,7 @@ </doc>""") self.assertEqual("""<doc> Hello - </doc>""", str(tmpl.generate(Context(foo=True, bar='Hello')))) + </doc>""", str(tmpl.generate(foo=True, bar='Hello'))) class MatchDirectiveTestCase(unittest.TestCase): @@ -427,7 +426,7 @@ 42 84 42 - </div>""", str(tmpl.generate(Context(x=42)))) + </div>""", str(tmpl.generate(x=42))) def test_as_element(self): tmpl = Template("""<div xmlns:py="http://markup.edgewall.org/"> @@ -435,7 +434,7 @@ </div>""") self.assertEqual("""<div> 84 - </div>""", str(tmpl.generate(Context(x=42)))) + </div>""", str(tmpl.generate(x=42))) class TemplateTestCase(unittest.TestCase): @@ -488,9 +487,8 @@ self.assertEqual(' baz', parts[2][1]) def test_interpolate_mixed3(self): - ctxt = Context(var=42) tmpl = Template('<root> ${var} $var</root>') - self.assertEqual('<root> 42 42</root>', str(tmpl.generate(ctxt))) + self.assertEqual('<root> 42 42</root>', str(tmpl.generate(var=42))) def test_interpolate_non_string_attrs(self): tmpl = Template('<root attr="${1}"/>') @@ -498,8 +496,7 @@ def test_interpolate_list_result(self): tmpl = Template('<root>$foo</root>') - ctxt = Context(foo=('buzz',)) - self.assertEqual('<root>buzz</root>', str(tmpl.generate(ctxt))) + self.assertEqual('<root>buzz</root>', str(tmpl.generate(foo=('buzz',)))) def test_empty_attr(self): tmpl = Template('<root attr=""/>') @@ -560,7 +557,7 @@ </div>""") self.assertEqual("""<div> <b>foo</b> - </div>""", str(tmpl.generate(Context(myvar=Markup('<b>foo</b>'))))) + </div>""", str(tmpl.generate(myvar=Markup('<b>foo</b>')))) def test_text_noescape_quotes(self): """ @@ -571,7 +568,7 @@ </div>""") self.assertEqual("""<div> "foo" - </div>""", str(tmpl.generate(Context(myvar='"foo"')))) + </div>""", str(tmpl.generate(myvar='"foo"'))) def test_attr_escape_quotes(self): """ @@ -582,7 +579,7 @@ </div>""") self.assertEqual("""<div> <elem class=""foo""/> - </div>""", str(tmpl.generate(Context(myvar='"foo"')))) + </div>""", str(tmpl.generate(myvar='"foo"'))) def test_directive_element(self): tmpl = Template("""<div xmlns:py="http://markup.edgewall.org/"> @@ -590,7 +587,7 @@ </div>""") self.assertEqual("""<div> bar - </div>""", str(tmpl.generate(Context(myvar='"foo"')))) + </div>""", str(tmpl.generate(myvar='"foo"'))) def test_normal_comment(self): tmpl = Template("""<div xmlns:py="http://markup.edgewall.org/">