Mercurial > genshi > mirror
diff markup/template.py @ 149:537f819c547b trunk
`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 | 47bbd9d2a5af |
children | d35688d16831 |
line wrap: on
line diff
--- 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