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
Copyright (C) 2012-2017 Edgewall Software