﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-wash-随笔分类-django、cherrpy、 turbogears、twisted..</title><link>http://www.blogjava.net/wash/category/6211.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 10:47:59 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 10:47:59 GMT</pubDate><ttl>60</ttl><item><title>Kid Language Specification</title><link>http://www.blogjava.net/wash/archive/2005/12/26/25455.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Mon, 26 Dec 2005 08:11:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2005/12/26/25455.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/25455.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2005/12/26/25455.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/25455.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/25455.html</trackback:ping><description><![CDATA[<DIV id=page>
<H1 class=doc-title><FONT size=3>Kid is a simple XML based template language that uses embedded </FONT><A class=reference href="http://www.python.org/"><FONT size=3>Python</FONT></A><FONT size=3> to do cool stuff. The syntax was inspired by a number of existing template languages, namely </FONT><A class=reference href="http://www.w3.org/TR/xslt"><FONT size=3>XSLT</FONT></A><FONT size=3>, </FONT><A class=reference href="http://www.zope.org/Wikis/DevSite/Projects/ZPT/TAL"><FONT size=3>TAL</FONT></A><FONT size=3>, and </FONT><A class=reference href="http://www.php.net/"><FONT size=3>PHP</FONT></A><FONT size=3>.</FONT></H1>
<DIV id=content>
<DIV class=rst-doc>
<P>This document describes the template language and will be most useful as reference to those developing Kid templates. For information about using templates from Python, the command line, or in web environments, see the <A class=reference href="http://kid.lesscode.org/guide.html">User's Guide</A>.</P>
<DIV class="contents topic" id=contents>
<P class="topic-title first"><A name=contents>Contents</A></P>
<UL class="auto-toc simple">
<LI><A class=reference id=id7 href="http://kid.lesscode.org/language.html#synopsis" name=id7>1&nbsp;&nbsp;&nbsp;Synopsis</A> 
<LI><A class=reference id=id8 href="http://kid.lesscode.org/language.html#the-kid-namespace" name=id8>2&nbsp;&nbsp;&nbsp;The Kid Namespace</A> 
<LI><A class=reference id=id9 href="http://kid.lesscode.org/language.html#embedding-code-blocks-python" name=id9>3&nbsp;&nbsp;&nbsp;Embedding Code Blocks (<TT class="docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT>)</A> 
<LI><A class=reference id=id10 href="http://kid.lesscode.org/language.html#content-producing-constructs" name=id10>4&nbsp;&nbsp;&nbsp;Content Producing Constructs</A> 
<LI><A class=reference id=id11 href="http://kid.lesscode.org/language.html#python-expression-substitution-expr" name=id11>5&nbsp;&nbsp;&nbsp;Python Expression Substitution (<TT class="docutils literal"><SPAN class=pre>${expr}</SPAN></TT>)</A> 
<UL class=auto-toc>
<LI><A class=reference id=id12 href="http://kid.lesscode.org/language.html#identifier-shortcut-name" name=id12>5.1&nbsp;&nbsp;&nbsp;Identifier Shortcut (<TT class="docutils literal"><SPAN class=pre>$name</SPAN></TT>)</A> 
<LI><A class=reference id=id13 href="http://kid.lesscode.org/language.html#escaping" name=id13>5.2&nbsp;&nbsp;&nbsp;Escaping (<TT class="docutils literal"><SPAN class=pre>$$</SPAN></TT>)</A> </LI></UL>
<LI><A class=reference id=id14 href="http://kid.lesscode.org/language.html#default-imports" name=id14>6&nbsp;&nbsp;&nbsp;Default Imports</A> 
<UL class=auto-toc>
<LI><A class=reference id=id15 href="http://kid.lesscode.org/language.html#xml-function" name=id15>6.1&nbsp;&nbsp;&nbsp;<TT class="docutils literal"><SPAN class=pre>XML()</SPAN></TT> function</A> 
<LI><A class=reference id=id16 href="http://kid.lesscode.org/language.html#document-function" name=id16>6.2&nbsp;&nbsp;&nbsp;<TT class="docutils literal"><SPAN class=pre>document()</SPAN></TT> function</A> </LI></UL>
<LI><A class=reference id=id17 href="http://kid.lesscode.org/language.html#attribute-language" name=id17>7&nbsp;&nbsp;&nbsp;Attribute Language</A> 
<UL class=auto-toc>
<LI><A class=reference id=id18 href="http://kid.lesscode.org/language.html#repetition-iteration-py-for" name=id18>7.1&nbsp;&nbsp;&nbsp;Repetition/Iteration (<TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT>)</A> 
<LI><A class=reference id=id19 href="http://kid.lesscode.org/language.html#conditionals-py-if" name=id19>7.2&nbsp;&nbsp;&nbsp;Conditionals (<TT class="docutils literal"><SPAN class=pre>py:if</SPAN></TT>)</A> 
<LI><A class=reference id=id20 href="http://kid.lesscode.org/language.html#dynamic-content-py-content" name=id20>7.3&nbsp;&nbsp;&nbsp;Dynamic Content (<TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT>)</A> 
<LI><A class=reference id=id21 href="http://kid.lesscode.org/language.html#replacing-content-py-replace" name=id21>7.4&nbsp;&nbsp;&nbsp;Replacing Content (<TT class="docutils literal"><SPAN class=pre>py:replace</SPAN></TT>)</A> 
<LI><A class=reference id=id22 href="http://kid.lesscode.org/language.html#stripping-tags-py-strip" name=id22>7.5&nbsp;&nbsp;&nbsp;Stripping Tags (<TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT>)</A> 
<LI><A class=reference id=id23 href="http://kid.lesscode.org/language.html#dynamic-attributes-py-attrs" name=id23>7.6&nbsp;&nbsp;&nbsp;Dynamic Attributes (<TT class="docutils literal"><SPAN class=pre>py:attrs</SPAN></TT>)</A> 
<LI><A class=reference id=id24 href="http://kid.lesscode.org/language.html#named-template-functions-py-def" name=id24>7.7&nbsp;&nbsp;&nbsp;Named Template Functions (<TT class="docutils literal"><SPAN class=pre>py:def</SPAN></TT>)</A> 
<LI><A class=reference id=id25 href="http://kid.lesscode.org/language.html#match-templates-py-match" name=id25>7.8&nbsp;&nbsp;&nbsp;Match Templates (<TT class="docutils literal"><SPAN class=pre>py:match</SPAN></TT>)</A> 
<LI><A class=reference id=id26 href="http://kid.lesscode.org/language.html#template-reuse-py-extends" name=id26>7.9&nbsp;&nbsp;&nbsp;Template Reuse (<TT class="docutils literal"><SPAN class=pre>py:extends</SPAN></TT>)</A> </LI></UL>
<LI><A class=reference id=id27 href="http://kid.lesscode.org/language.html#processing-order" name=id27>8&nbsp;&nbsp;&nbsp;Processing Order</A> 
<LI><A class=reference id=id28 href="http://kid.lesscode.org/language.html#revision-history" name=id28>9&nbsp;&nbsp;&nbsp;Revision History</A> 
<UL class=auto-toc>
<LI><A class=reference id=id29 href="http://kid.lesscode.org/language.html#revision-4-kid-v0-6" name=id29>9.1&nbsp;&nbsp;&nbsp;Revision 4 (Kid v0.6)</A> 
<LI><A class=reference id=id30 href="http://kid.lesscode.org/language.html#revision-3-kid-v0-5" name=id30>9.2&nbsp;&nbsp;&nbsp;Revision 3 (Kid v0.5)</A> 
<LI><A class=reference id=id31 href="http://kid.lesscode.org/language.html#revision-2" name=id31>9.3&nbsp;&nbsp;&nbsp;Revision 2</A> 
<LI><A class=reference id=id32 href="http://kid.lesscode.org/language.html#revision-1" name=id32>9.4&nbsp;&nbsp;&nbsp;Revision 1</A> </LI></UL></LI></UL></DIV>
<DIV class=section id=synopsis>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id7" name=synopsis>1&nbsp;&nbsp;&nbsp;Synopsis</A></H1><PRE class=literal-block>&lt;?python
title = "A Kid Test Document"
fruits = ["apple", "orange", "kiwi", "M&amp;M"]
from platform import system
?&gt;
&lt;html xmlns:py="http://purl.org/kid/ns#"&gt;
  &lt;head&gt;
    &lt;title py:content="title"&gt;This is replaced.&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;These are some of my favorite fruits:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li py:for="fruit in fruits"&gt;
        I like ${fruit}s
      &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p py:if="system() == 'Linux'"&gt;
      Good for you!
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</PRE>
<P>Yields something like this:</P><PRE class=literal-block>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;A Kid Test Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;These are some of my favorite fruits:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;I like apples&lt;/li&gt;
      &lt;li&gt;I like oranges&lt;/li&gt;
      &lt;li&gt;I like kiwis&lt;/li&gt;
      &lt;li&gt;I like M&amp;amp;Ms&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;
      Good for you!
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</PRE></DIV>
<DIV class=section id=the-kid-namespace>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id8" name=the-kid-namespace>2&nbsp;&nbsp;&nbsp;The Kid Namespace</A></H1>
<P>All attributes described in this document must belong to the following namespace:</P><PRE class=literal-block>http://purl.org/kid/ns#
</PRE>
<P>The namespace prefix <TT class="docutils literal"><SPAN class=pre>py</SPAN></TT> is used throughout this document to indicate that an item belongs to the Kid/Python namespace.</P></DIV>
<DIV class=section id=embedding-code-blocks-python>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id9" name=embedding-code-blocks-python>3&nbsp;&nbsp;&nbsp;Embedding Code Blocks (<TT class="docutils literal docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT>)</A></H1>
<P>The <TT class="docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT> processing instruction (PI) contains Python code and <EM>MAY</EM> occur anywhere that is legal for processing instructions to occur in an XML document.</P>
<P>The rules for executing code found in a <TT class="docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT> PI is as follows:</P>
<OL class="arabic simple">
<LI><TT class="docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT> PIs located outside of the document element (e.g. root element) contain <EM>Document Level</EM> code. This code <EM>SHOULD</EM> be executed in a global, shared scope for the document. The code <EM>SHOULD</EM> be executed once when the template is loaded and shared between multiple invocations of the template. 
<LI><TT class="docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT> PIs located within the document element contain <EM>Local Level</EM> code. This code is executed each time the document is processed with a local scope specific to the invocation and the shared document level global scope. </LI></OL>
<P><EM>Document Level</EM> and <EM>Local Level</EM> code work exactly like <EM>Module Level</EM> and <EM>Function Level</EM> code in normal Python modules. For example, the following Kid template:</P><PRE class=literal-block>&lt;?python
x = 0
y = 0
?&gt;
&lt;html xmlns:py="http://purl.org/kid/ns#"&gt;
  &lt;?python
  x = 1
  if x == 1:
    x = 10
  ?&gt;
  &lt;p py:content="x"/&gt;
  &lt;?python
  global y
  y = 30
  ?&gt;
  &lt;p py:content="y"/&gt;
&lt;/html&gt;
</PRE>
<P>May be considered equivalent to the following Python module:</P><PRE class=literal-block>x = 0
y = 0
def expand(handler):
  handler.startDocument()
  handler.startElement('html')
  x = 1
  if x == 1:
    x = 10
  handler.element('p', content=x) # output p element with x as value
  global y
  y = 30
  handler.element('p', content=y) # output p element with value of y
  handler.endElement('html')
  handler.endDocument()
</PRE>
<P><TT class="docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT> PIs may contain any legal Python language construct including functions, classes, lamda forms, etc.</P><PRE class=literal-block>&lt;?python
class Adder:
  def __init__(self, x, y):
    self.x = x
    self.y = y
  def doit(self):
    return self.x + self.y

foo = Adder(x=400, y=20)
x = foo.doit()
?&gt;
</PRE>
<P>Single line <TT class="docutils literal"><SPAN class=pre>&lt;?python?&gt;</SPAN></TT> PIs are okay too:</P><PRE class=literal-block>&lt;?python x = 10 ?&gt;
</PRE></DIV>
<DIV class=section id=content-producing-constructs><SPAN id=content-producing-construct></SPAN>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id10" name=content-producing-constructs>4&nbsp;&nbsp;&nbsp;Content Producing Constructs</A></H1>
<P>There are multiple methods of generating content output from a template: <TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>py:replace</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>py:attrs</SPAN></TT>, and <TT class="docutils literal"><SPAN class=pre>${}</SPAN></TT> substitution. Each of these syntaxes have the same rules for what types of objects may result from the Python expression they contain.</P>
<DL class=docutils>
<DT><TT class="docutils literal"><SPAN class=pre>str</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>unicode</SPAN></TT> 
<DD>The string is inserted as XML CDATA. That is, it is non-parsable character data that does not contain markup. The following characters are encoded as XML entities when serialized: '&lt;', '&amp;'. Attribute values containing content also encode the quote character: '"'. 
<DT><TT class="docutils literal"><SPAN class=pre>ElementTree.Element</SPAN></TT> 
<DD>
<P class=first>When an <TT class="docutils literal"><SPAN class=pre>ElementTree.Element</SPAN></TT> is referenced from a content producing construct, the item is inserted into the document literally, i.e. it is not encoded as text, but becomes part of the output structure.</P>
<P>The <TT class="docutils literal"><SPAN class=pre>XML()</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>document()</SPAN></TT> functions can be used to turn a string into structured content and to retrieve an XML document from a URL, respectively.</P>
<P class=last>Note that attribute values <EM>MUST NOT</EM> reference structured content. This applies to <TT class="docutils literal"><SPAN class=pre>py:attrs</SPAN></TT> and using <TT class="docutils literal"><SPAN class=pre>${}</SPAN></TT> substitution in attribute values.</P>
<DT><EM>sequence</EM> 
<DD>If a sequence type (<TT class="docutils literal"><SPAN class=pre>list</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>tuple</SPAN></TT>, or other iterable) is referenced, the rules are applied to each of the items in the sequence. For example, you could reference a list containing an <TT class="docutils literal"><SPAN class=pre>Element</SPAN></TT> and a string. 
<DT>Other 
<DD>If the result of evaluating the expression is any other type, an attempt is made to coerce the value to unicode as if by calling <TT class="docutils literal"><SPAN class=pre>unicode(expr)</SPAN></TT> and processing continues as if the object were a string or unicode object initially. </DD></DL></DIV>
<DIV class=section id=python-expression-substitution-expr><SPAN id=expression-substitution></SPAN>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id11" name=python-expression-substitution-expr>5&nbsp;&nbsp;&nbsp;Python Expression Substitution (<TT class="docutils literal docutils literal"><SPAN class=pre>${expr}</SPAN></TT>)</A></H1>
<P>Attributes not belonging to the Kid namespace and text content <EM>MAY</EM> embed Python expressions by enclosing the expression within a dollar sign followed by curly braces: <TT class="docutils literal"><SPAN class=pre>${expr}</SPAN></TT>. The result of evaluating the expression(s) is substituted with the rest of the attribute value or text content following rules defined for <A class=reference href="http://kid.lesscode.org/language.html#content-producing-constructs">Content Producing Constructs</A>.</P><PRE class=literal-block>&lt;?python
verb = 'ran'
noun = 'store'
?&gt;
&lt;a title="I ${verb} to the ${noun}"&gt;...
</PRE>
<P>... would result in:</P><PRE class=literal-block>&lt;a title="I ran to the store"&gt;...
</PRE>
<P>If an attribute value consists purely of substitution expressions and all expressions evaluate to <TT class="docutils literal"><SPAN class=pre>None</SPAN></TT>, the attribute is removed. This can be avoided by using <TT class="docutils literal"><SPAN class=pre>expr</SPAN> <SPAN class=pre>or</SPAN> <SPAN class=pre>''</SPAN></TT> to force a zero length string to be returned instead of <TT class="docutils literal"><SPAN class=pre>None</SPAN></TT>. For example:</P><PRE class=literal-block>&lt;?python
# set something to None
x = None
?&gt;
&lt;a title="${x}"&gt;...
</PRE>
<P>... would result in:</P><PRE class=literal-block>&lt;a&gt;...
</PRE>
<P>However, this:</P><PRE class=literal-block>&lt;?python x = None?&gt;
&lt;a title="${x or ''}"&gt;...
</PRE>
<P>... results in:</P><PRE class=literal-block>&lt;a title=""&gt;...
</PRE>
<DIV class=section id=identifier-shortcut-name>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id12" name=identifier-shortcut-name>5.1&nbsp;&nbsp;&nbsp;Identifier Shortcut (<TT class="docutils literal docutils literal"><SPAN class=pre>$name</SPAN></TT>)</A></H2>
<P>For simple expressions consisting entirely variable names and object access operators (.), the curly braces may be omitted:</P><PRE class=literal-block>&lt;a href="http://example.com/$page" title="$title"&gt;
   Dots are allowed too: $object.another.attribute
&lt;/a&gt;
</PRE>
<P>However, it is good practice to use the curly brace form as it sets the substitution off from the other text a bit more providing a stronger visual clue as to what's going on.</P></DIV>
<DIV class=section id=escaping>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id13" name=escaping>5.2&nbsp;&nbsp;&nbsp;Escaping (<TT class="docutils literal docutils literal"><SPAN class=pre>$$</SPAN></TT>)</A></H2>
<P><TT class="docutils literal"><SPAN class=pre>$$</SPAN></TT> is an escape. <TT class="docutils literal"><SPAN class=pre>$${bla}</SPAN></TT> will output <TT class="docutils literal"><SPAN class=pre>${bla}</SPAN></TT>.</P></DIV></DIV>
<DIV class=section id=default-imports>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id14" name=default-imports>6&nbsp;&nbsp;&nbsp;Default Imports</A></H1>
<P>All templates have a few default imports for convenience.</P>
<DIV class=section id=xml-function>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id15" name=xml-function>6.1&nbsp;&nbsp;&nbsp;<TT class="docutils literal docutils literal"><SPAN class=pre>XML()</SPAN></TT> function</A></H2>
<P><A class=reference href="http://kid.lesscode.org/language.html#expression-substitution">Expression substitution</A>, <A class=reference href="http://kid.lesscode.org/language.html#py-content">py:content</A>, and <A class=reference href="http://kid.lesscode.org/language.html#py-replace">py:replace</A> encode strings as text. That is, text is encoded according to the rules of the XML specification, which includes, among other things, replacing the literal characters <TT class="docutils literal"><SPAN class=pre>&lt;</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>&amp;</SPAN></TT> with their encoded counterparts (<TT class="docutils literal"><SPAN class=pre>&amp;lt;</SPAN></TT> <TT class="docutils literal"><SPAN class=pre>&amp;amp;</SPAN></TT>). If you have XML stored as a string and want it to be output as XML and not encoded text, you need to pass the string to the <TT class="docutils literal"><SPAN class=pre>XML</SPAN></TT> function.</P>
<P>For example, let's say there is a function, <TT class="docutils literal"><SPAN class=pre>hello</SPAN></TT>, that returns XML data that should be embedded in template output (let's say it returns <TT class="docutils literal"><SPAN class=pre>&lt;hello&gt;world&lt;/hello&gt;</SPAN></TT>). Consider the following:</P><PRE class=literal-block>&lt;p&gt;${hello()}&lt;/p&gt;
</PRE>
<P>The result would be:</P><PRE class=literal-block>&lt;p&gt;&amp;lt;hello&gt;world&amp;lt;hello&gt;&lt;/p&gt;
</PRE>
<P>Calling the <TT class="docutils literal"><SPAN class=pre>XML</SPAN></TT> function would have given us the result we intended:</P><PRE class=literal-block>&lt;p&gt;${XML(hello())}&lt;/p&gt;
</PRE><PRE class=literal-block>&lt;p&gt;&lt;hello&gt;world&lt;/hello&gt;&lt;/p&gt;
</PRE></DIV>
<DIV class=section id=document-function>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id16" name=document-function>6.2&nbsp;&nbsp;&nbsp;<TT class="docutils literal docutils literal"><SPAN class=pre>document()</SPAN></TT> function</A></H2>
<P>The <TT class="docutils literal"><SPAN class=pre>document</SPAN></TT> function loads an XML document from a file or URL allowing it to be embedded in template output:</P><PRE class=literal-block>&lt;div py:content="document('header.html')"&gt;&lt;/div&gt;
</PRE>
<P>The document function resolves paths relative to the current template file (if the template location is available).</P></DIV></DIV>
<DIV class=section id=attribute-language>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id17" name=attribute-language>7&nbsp;&nbsp;&nbsp;Attribute Language</A></H1>
<DIV class=section id=repetition-iteration-py-for><SPAN id=py-for></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id18" name=repetition-iteration-py-for>7.1&nbsp;&nbsp;&nbsp;Repetition/Iteration (<TT class="docutils literal docutils literal"><SPAN class=pre>py:for</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:for="target_list in expression_list" /&gt;
</PRE>
<P>Works exactly like the <A class=reference href="http://www.python.org/dev/doc/devel/ref/for.html">Python for statement</A>.</P>
<P>The <TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT> attribute <EM>may</EM> appear on any element to signify that the element should be processed multiple times, once for each value in the sequence specified:</P><PRE class=literal-block>&lt;?python
bottles = range(1, 101)
bottles.reverse()
?&gt;
&lt;p py:for="num in bottles"&gt;
   &lt;span py:content="num"&gt;X&lt;/span&gt; bottles of beer on the wall,
   &lt;span py:content="num"&gt;X&lt;/span&gt; bottles of beer on the wall,
   take one down, pass it around, &lt;span py:content="num - 1"&gt;X - 1&lt;/span&gt;
   bottles of beer on the wall.
&lt;/p&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT> attribute is the first attribute to be processed if present. All other <TT class="docutils literal"><SPAN class=pre>py:</SPAN></TT> attributes are processed for each iteration of the loop.</P></DIV>
<DIV class=section id=conditionals-py-if><SPAN id=py-if></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id19" name=conditionals-py-if>7.2&nbsp;&nbsp;&nbsp;Conditionals (<TT class="docutils literal docutils literal"><SPAN class=pre>py:if</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:if="expr" /&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:if</SPAN></TT> attribute may appear on any element to signify that the element and its decendant items should be output only if the boolean expression specified evaluates to true in Python:</P><PRE class=literal-block>&lt;p py:if="5 * 5 == 25"&gt;
  Python seems to be handling multiplication okay.
&lt;/p&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:if</SPAN></TT> attribute is processed after the <TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT> attribute and is evaluated for each iteration. If the result of evaluating <TT class="docutils literal"><SPAN class=pre>expr</SPAN></TT> as a boolean expression is false in Python, no further <TT class="docutils literal"><SPAN class=pre>py:</SPAN></TT> attributes are processed for the current iteration or, if not in a <TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT>, at all.</P>
<DIV class=note>
<P class="first admonition-title">Note</P>
<P class=last>Evaluated as a boolean expression in Python, <TT class="docutils literal"><SPAN class=pre>None</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>False</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>[]</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>()</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>{}</SPAN></TT>, <TT class="docutils literal"><SPAN class=pre>0</SPAN></TT>, and <TT class="docutils literal"><SPAN class=pre>''</SPAN></TT> are all considered to be false.</P></DIV></DIV>
<DIV class=section id=dynamic-content-py-content><SPAN id=py-content></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id20" name=dynamic-content-py-content>7.3&nbsp;&nbsp;&nbsp;Dynamic Content (<TT class="docutils literal docutils literal"><SPAN class=pre>py:content</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:content="expr" /&gt;
</PRE>
<P>This attribute <EM>MAY</EM> appear on any element to signify that the decendant items of the element are to be replaced with the result of evaluating <TT class="docutils literal"><SPAN class=pre>expr</SPAN></TT>.</P><PRE class=literal-block>&lt;p py:content="time.strftime('%C %c')"&gt;The Time&lt;/p&gt;
</PRE>
<P>Results in:</P><PRE class=literal-block>&lt;p&gt;Tues, Jun 26, 2004 02:03:53 AM&lt;/p&gt;
</PRE>
<P><TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT> is a <A class=reference href="http://kid.lesscode.org/language.html#content-producing-construct">Content Producing Construct</A> and can output both character and structured data.</P></DIV>
<DIV class=section id=replacing-content-py-replace><SPAN id=py-replace></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id21" name=replacing-content-py-replace>7.4&nbsp;&nbsp;&nbsp;Replacing Content (<TT class="docutils literal docutils literal"><SPAN class=pre>py:replace</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:replace='expr' /&gt;
</PRE>
<P><TT class="docutils literal"><SPAN class=pre>py:replace</SPAN></TT> is shorthand for specifying a <TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT> and a <TT class="docutils literal"><SPAN class=pre>py:strip="True"</SPAN></TT> on the same element:</P><PRE class=literal-block>&lt;?python
x = 10
?&gt;
&lt;p&gt;&lt;span py:replace="x"&gt;...&lt;/span&gt;&lt;/p&gt;
</PRE>
<P>... results in:</P><PRE class=literal-block>&lt;p&gt;10&lt;/p&gt;
</PRE>
<P>... and is equivelant to specifying:</P><PRE class=literal-block>&lt;?python #
x = 10
?&gt;
&lt;p&gt;&lt;span py:strip="" py:content="x"&gt;...&lt;/span&gt;&lt;/p&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:replace</SPAN></TT> attribute is processed after the <TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>py:if</SPAN></TT> attributes. <TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT> attributes are not processed and are discarded.</P>
<P><TT class="docutils literal"><SPAN class=pre>py:replace</SPAN></TT> is a <A class=reference href="http://kid.lesscode.org/language.html#content-producing-construct">Content Producing Construct</A> and can output both character and structured data.</P></DIV>
<DIV class=section id=stripping-tags-py-strip><SPAN id=py-strip></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id22" name=stripping-tags-py-strip>7.5&nbsp;&nbsp;&nbsp;Stripping Tags (<TT class="docutils literal docutils literal"><SPAN class=pre>py:strip</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:strip="expr" /&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT> attribute may apppear on any element to signify that the containing element should not be output. If the attribute value is blank (no <TT class="docutils literal"><SPAN class=pre>expr</SPAN></TT> at all) or if the result <TT class="docutils literal"><SPAN class=pre>expr</SPAN></TT> is a boolean expression that evaluates to true, the element is not output, but all descendant elements are processed normally. If <TT class="docutils literal"><SPAN class=pre>expr</SPAN></TT> is not blank and the result of evaluating <TT class="docutils literal"><SPAN class=pre>expr</SPAN></TT> as a boolean expression is false, processing continues as if the attribute did not exist.</P>
<P>The <TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT> attribute <EM>MAY</EM> appear on an element with any other kid attribute. However, if both a <TT class="docutils literal"><SPAN class=pre>py:replace</SPAN></TT> and a <TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT> exist on the same element, the <TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT> attribute is ignored and discarded.</P>
<P>The <TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT> attribute is processed after the <TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>py:if</SPAN></TT> attributes. If omission is eminent, the <TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT> attribute is processed normally but attribute interpolation does not occur.</P></DIV>
<DIV class=section id=dynamic-attributes-py-attrs><SPAN id=py-attrs></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id23" name=dynamic-attributes-py-attrs>7.6&nbsp;&nbsp;&nbsp;Dynamic Attributes (<TT class="docutils literal docutils literal"><SPAN class=pre>py:attrs</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:attrs="expr" /&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:attrs</SPAN></TT> attribute may appear on any element to specify a set of attributes that should be set on the element when it is processed. The expression specified MUST evaluate to one of the following types of values:</P>
<DL class=docutils>
<DT>dict 
<DD>A dictionary with keys specifying attribute names and values specifying attribute values. These are added to the attributes of the current element by calling <TT class="docutils literal"><SPAN class=pre>element.attrib.update(mapping)</SPAN></TT>, where <TT class="docutils literal"><SPAN class=pre>element</SPAN></TT> is an ElementTree Element object and <TT class="docutils literal"><SPAN class=pre>mapping</SPAN></TT> is the dictionary returned from the expression. Outer curly braces are not necessary to write down. 
<DT>list 
<DD>A list of tuples of the form <TT class="docutils literal"><SPAN class=pre>(name,</SPAN> <SPAN class=pre>value)</SPAN></TT> is also acceptable. Each item of the list is added to the current set of attributes by iterating over the list and calling <TT class="docutils literal"><SPAN class=pre>element.set(name,</SPAN> <SPAN class=pre>value)</SPAN></TT>. 
<DT>keyword arguments 
<DD>The attributes can also be specified as comma separated keyword arguments of the form <TT class="docutils literal"><SPAN class=pre>name=value</SPAN></TT>. </DD></DL>
<P>The following lines:</P><PRE class=literal-block>&lt;elem py:attrs="{'a':1, 'ns:b':2}" /&gt;
&lt;elem py:attrs="'a':1, 'ns:b':2" /&gt;
&lt;elem py:attrs="(('a',1), ('ns:b',2))" /&gt;
&lt;elem py:attrs="a=1, ns:b=2" /&gt;
</PRE>
<P>will all produce the same output:</P><PRE class=literal-block>&lt;elem a="1" ns:b="2" /&gt;
</PRE>
<P>Note that attributes whose values are <TT class="docutils literal"><SPAN class=pre>None</SPAN></TT> will be removed. If a blank attribute is desired, an empty string should be used.</P>
<P>If the expression specified is an empty dictionary or an empty list, the attributes are not modified in any way.</P>
<P><TT class="docutils literal"><SPAN class=pre>py:attrs</SPAN></TT> is a <A class=reference href="http://kid.lesscode.org/language.html#content-producing-construct">Content Producing Construct</A>, but can output only character data.</P></DIV>
<DIV class=section id=named-template-functions-py-def><SPAN id=named-template-functions></SPAN><SPAN id=py-def></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id24" name=named-template-functions-py-def>7.7&nbsp;&nbsp;&nbsp;Named Template Functions (<TT class="docutils literal docutils literal"><SPAN class=pre>py:def</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:def="template_name(arg_list)" /&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:def</SPAN></TT> attribute may appear on any element to create a "Named Template Function". Markup contained within an <TT class="docutils literal"><SPAN class=pre>py:def</SPAN></TT> element is not output during normal template expansion but can be referenced from other <A class=reference href="http://kid.lesscode.org/language.html#content-producing-constructs">Content Producing Constructs</A> to insert the markup at the point referenced.</P>
<P>Like normal Python functions, Named Template Functions have an optional argument list that may use all of the jazzy features of Python argument lists like variable and keyword arguments.</P>
<P>Named Template Functions are invoked exactly like normal Python functions. They are generally invoked from <A class=reference href="http://kid.lesscode.org/language.html#content-producing-constructs">Content Producing Constructs</A> like <TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT> or <TT class="docutils literal"><SPAN class=pre>${}</SPAN></TT> substitution.</P><PRE class=literal-block>&lt;ul py:def="display_list(seq)"&gt;
   &lt;li py:for="item in seq" py:content="item" /&gt;
&lt;/ul&gt;

&lt;table py:def="display_dict(mapping)"&gt;
   &lt;tr&gt;
       &lt;th&gt;Key&lt;/th&gt;
       &lt;th&gt;Value&lt;/th&gt;
   &lt;/tr&gt;
   &lt;tr py:for="key, value in mapping.items()"&gt;
       &lt;td py:content="key" /&gt;
       &lt;td py:content="value" /&gt;
   &lt;/tr&gt;
&lt;/table&gt;
</PRE>
<P>Here we've defined two Named Template Functions: <TT class="docutils literal"><SPAN class=pre>display_list</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>display_dict</SPAN></TT>. The first function takes a sequence and the second a mapping. We can invoke these functions from the same template by invoking them from a content producing construct:</P><PRE class=literal-block>&lt;body&gt;
   ${display_list(['apple', 'orange', 'kiwi'])}

   &lt;div py:replace="display_dict({'x' : 'y', 'p' : 'q'})"&gt;
    Key/Value Table replaces this text
   &lt;/div&gt;
&lt;/body&gt;
</PRE></DIV>
<DIV class=section id=match-templates-py-match><SPAN id=match-templates></SPAN><SPAN id=py-match></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id25" name=match-templates-py-match>7.8&nbsp;&nbsp;&nbsp;Match Templates (<TT class="docutils literal docutils literal"><SPAN class=pre>py:match</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;element py:match="expr" /&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:match</SPAN></TT> attribute may appear on any element to create a "Match Template". Markup contained within a Match Template element is not output during normal template expansion. Instead, these constructs set up filters for expansion output that are capable of transforming content as it is generated.</P>
<P>Match Templates are generally used to insert content dynamically based on patterns in template expansion or to provide "custom tag" functionality similar to that found in JSP taglibs or XSLT.</P>
<P>A Match Template has two parts: the match expression part (<TT class="docutils literal"><SPAN class=pre>expr</SPAN></TT>) and the body part (the element and it's descendants).</P>
<P>Match Templates are processed as follows:</P>
<OL class="arabic simple">
<LI>Each element that is output from a template goes through the Match Template Filter. 
<LI>The Match Template Filter visits each of the Match Templates defined in the current template and the templates the current template <A class=reference href="http://kid.lesscode.org/language.html#extends">extends</A> in the order that they are defined and evaluates the associated match expression. 
<LI>If the match expression returns true as a boolean expression, the match template's body is expanded and replaces the original element and all of its descendants. </LI></OL>
<P>In both the match expression and in the match template's body, the <TT class="docutils literal"><SPAN class=pre>item</SPAN></TT> name is bound to the Element that is being output. However, there are some limitations to what can be accessed at each phase:</P>
<OL class="arabic simple">
<LI>During match expression evaluation, only the <TT class="docutils literal"><SPAN class=pre>item</SPAN></TT> Element and none of its descendants are available. This means that match expressions are limited to testing matches based on the immediate Element's tag and attributes <A class=footnote-reference id=id4 href="http://kid.lesscode.org/language.html#id5" name=id4>[1]</A>. 
<LI>During match template expansion (that is, when the match expression is true), the element's descendants <EM>are</EM> available and may be referenced from <A class=reference href="http://kid.lesscode.org/language.html#content-producing-constructs">Content Producing Constructs</A> to output bits and pieces of the matched items structure. </LI></OL>
<TABLE class="docutils footnote" id=id5 rules=none frame=void>
<COLGROUP>
<COL class=label>
<COL></COLGROUP>
<TBODY vAlign=top>
<TR>
<TD class=label><A class=fn-backref href="http://kid.lesscode.org/language.html#id4" name=id5>[1]</A></TD>
<TD>This is due to the streaming nature of the Kid processor. During normal template expansion, the entire tree is never fully retained in memory.</TD></TR></TBODY></TABLE>
<DIV class=section id=example>
<H3><A name=example>7.8.1&nbsp;&nbsp;&nbsp;Example</A></H3>
<P>The following simple example shows how to create a custom tag <TT class="docutils literal"><SPAN class=pre>&lt;greeting&gt;</SPAN></TT> that outputs one of two provided values based on the time of day the template is expanded:</P><PRE class=literal-block>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;?python
from time import localtime
def timeofday():
    """Get time of day ('am' or 'pm')"""
    return localtime().tm_hour &lt; 12 and 'am' or 'pm'
?&gt;
&lt;html xmlns:py="http://purl.org/kid/ns#"&gt;
  &lt;!-- define the greeting match template --&gt;
  &lt;span py:match="item.tag == 'greeting'"
        py:replace="item.get(timeofday())"&gt;
  &lt;/span&gt;

  &lt;head&gt;
    &lt;title&gt;Time of day demo&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;
      Good &lt;greeting am="Morning!" pm="Afternoon" /&gt;
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</PRE>
<P>An important thing to note is that the <TT class="docutils literal"><SPAN class=pre>py:match</SPAN></TT> expression and the match template body have access to the <TT class="docutils literal"><SPAN class=pre>&lt;greeting&gt;</SPAN></TT> element via the variable <TT class="docutils literal"><SPAN class=pre>item</SPAN></TT>. The <TT class="docutils literal"><SPAN class=pre>item.get(timeofday())</SPAN></TT> bit retrieves the value of the <TT class="docutils literal"><SPAN class=pre>am</SPAN></TT> attribute or the <TT class="docutils literal"><SPAN class=pre>pm</SPAN></TT> attribute based on what is returned from the <TT class="docutils literal"><SPAN class=pre>timeofday</SPAN></TT> function.</P>
<P>At 9:00 AM, output from this template would look like this:</P><PRE class=literal-block>&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Time of day demo&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;
      Good Morning!
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</PRE>
<P>The obvious question at this point is how to reuse Match Templates? The example above demonstrates the use of a Match Template from the same main template but it is often desirable to have "libraries" of Match Templates that could be used by multiple individual templates. The answer is to have the main template <A class=reference href="http://kid.lesscode.org/language.html#extend">extend</A> a common template containing the Match Templates needed. We can rewrite the above example as two separate templates: <TT class="docutils literal"><SPAN class=pre>main.kid</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>common.kid</SPAN></TT>.</P>
<P>The common template would look like this:</P><PRE class=literal-block>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;?python
from time import localtime
def timeofday():
    """Get time of day ('am' or 'pm')"""
    return localtime().tm_hour &lt; 12 and 'am' or 'pm'
?&gt;
&lt;html xmlns:py="http://purl.org/kid/ns#"&gt;
  &lt;!-- define the greeting match template --&gt;
  &lt;span py:match="item.tag == 'greeting'"
        py:replace="item.get(timeofday())"&gt;
  &lt;/span&gt;
&lt;/html&gt;
</PRE>
<P>And the main template would look like this:</P><PRE class=literal-block>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;html py:extends="'common.kid'"&gt;
  &lt;head&gt;
    &lt;title&gt;Time of day demo&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;
      Good &lt;greeting am="Morning!" pm="Afternoon" /&gt;
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</PRE>
<P>When a template <A class=reference href="http://kid.lesscode.org/language.html#extends">extends</A> another template (or set of templates), all of the Match Templates and <A class=reference href="http://kid.lesscode.org/language.html#named-template-functions">Named Template Functions</A> of the extended templates are available as if they were defined locally.</P>
<DIV class=warning>
<P class="first admonition-title">Warning</P>
<P class=last>Match templates are an experimental feature. Syntax and semantics may change significantly or be removed entirely in future release. Actually, this statement applies to many aspects of Kid but this one is especially unstable.</P></DIV></DIV></DIV>
<DIV class=section id=template-reuse-py-extends><SPAN id=template-reuse></SPAN><SPAN id=extend></SPAN><SPAN id=extends></SPAN><SPAN id=py-extends></SPAN>
<H2><A class=toc-backref href="http://kid.lesscode.org/language.html#id26" name=template-reuse-py-extends>7.9&nbsp;&nbsp;&nbsp;Template Reuse (<TT class="docutils literal docutils literal"><SPAN class=pre>py:extends</SPAN></TT>)</A></H2><PRE class=literal-block>&lt;root py:extends="template1, template2, ..."&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>py:extends</SPAN></TT> attribute may appear on the root element to specify that the template should inherit the <A class=reference href="http://kid.lesscode.org/language.html#named-template-functions">Named Template Functions</A> and <A class=reference href="http://kid.lesscode.org/language.html#match-templates">Match Templates</A> defined in another template (or set of templates). If a <TT class="docutils literal"><SPAN class=pre>py:extends</SPAN></TT> attribute is specified, it MUST be on the root element of the document.</P>
<P>The <TT class="docutils literal"><SPAN class=pre>py:extends</SPAN></TT> may contain a list of Python expressions separated by commas that reference templates. The rules for what types of values may be specified are:</P>
<DL class=docutils>
<DT>string 
<DD>
<P class=first>The name of a template file, relative to the current template file.</P>
<P>Example:</P><PRE class="last literal-block">&lt;html py:extends="'common.kid'" /&gt;
</PRE>
<DT>module or Template class 
<DD>
<P class=first>The <TT class="docutils literal"><SPAN class=pre>py:extends</SPAN></TT> variable references a module or a Template class. If a module is referenced, an attempt is made to find a class named <TT class="docutils literal"><SPAN class=pre>Template</SPAN></TT> belonging to the that module.</P>
<P>Example:</P><PRE class="last literal-block">&lt;?python
import common
?&gt;
&lt;html py:extends="common" ...
</PRE></DD></DL>
<P>Multiple templates may be referenced by separating each by a comma. The following example references templates <TT class="docutils literal"><SPAN class=pre>common</SPAN></TT> and <TT class="docutils literal"><SPAN class=pre>forms</SPAN></TT>, imported using the import hooks and a template filename named <TT class="docutils literal"><SPAN class=pre>other.kid</SPAN></TT>:</P><PRE class=literal-block>&lt;?python
import common, forms
?&gt;
&lt;html py:extends="common, forms, 'other.kid'" ...
</PRE>
<DIV class=section id=id6>
<H3><A name=id6>7.9.1&nbsp;&nbsp;&nbsp;Example</A></H3>
<P>For example, there is a template named <TT class="docutils literal"><SPAN class=pre>common.kid</SPAN></TT> that defines a template function, <TT class="docutils literal"><SPAN class=pre>display_errors</SPAN></TT>, and a match template that converts <TT class="docutils literal"><SPAN class=pre>&lt;b&gt;</SPAN></TT> elements to <TT class="docutils literal"><SPAN class=pre>&lt;strong&gt;</SPAN></TT> elements with uppercase content:</P><PRE class=literal-block>&lt;html xmlns:py="http://purl.org/kid/ns#"&gt;

  &lt;ul py:def="display_errors(errors)"&gt;
    &lt;li py:for="error in errors" py:content="error" /&gt;
  &lt;/ul&gt;

  &lt;strong py:match="item.tag == 'b'"
    py:content="item.text.upper()" /&gt;

&lt;/html&gt;
</PRE>
<P>The functions and match templates may be imported into another template by referencing them with <TT class="docutils literal"><SPAN class=pre>py:extends</SPAN></TT>:</P><PRE class=literal-block>&lt;html py:extends="'common.kid'"
      xmlns:py="http://purl.org/kid/ns#"&gt;
  &lt;head&gt;
    &lt;title&gt;Errors&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;The following &lt;b&gt;errors&lt;/b&gt; were found:&lt;/p&gt;
    ${ display_errors(["Field is required", "Must be phone number.."]) }
  &lt;/body&gt;
&lt;/html&gt;
</PRE>
<P>The <TT class="docutils literal"><SPAN class=pre>&lt;b&gt;errors&lt;/b&gt;</SPAN></TT> item is transformed to <TT class="docutils literal"><SPAN class=pre>&lt;strong&gt;ERRORS&lt;/strong&gt;</SPAN></TT> and the error list is displayed. Both the match template and the named template function are available in the derived template as if they were defined locally.</P></DIV></DIV></DIV>
<DIV class=section id=processing-order><SPAN id=order></SPAN>
<H1><A class=toc-backref href="http://kid.lesscode.org/language.html#id27" name=processing-order>8&nbsp;&nbsp;&nbsp;Processing Order</A></H1>
<P>The order that <TT class="docutils literal"><SPAN class=pre>py:</SPAN></TT> attributes are processed is as follows:</P>
<OL class="arabic simple">
<LI><TT class="docutils literal"><SPAN class=pre>py:def</SPAN></TT> 
<LI><TT class="docutils literal"><SPAN class=pre>py:match</SPAN></TT> 
<LI><TT class="docutils literal"><SPAN class=pre>py:for</SPAN></TT> 
<LI><TT class="docutils literal"><SPAN class=pre>py:if</SPAN></TT> 
<LI><TT class="docutils literal"><SPAN class=pre>py:replace</SPAN></TT> 
<LI><TT class="docutils literal"><SPAN class=pre>py:strip</SPAN></TT> 
<LI><TT class="docutils literal"><SPAN class=pre>py:attrs</SPAN></TT> 
<LI><TT class="docutils literal"><SPAN class=pre>py:content</SPAN></TT> </LI></OL>
<P>Attribute substitution occurs after all other </P></DIV></DIV></DIV></DIV><img src ="http://www.blogjava.net/wash/aggbug/25455.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2005-12-26 16:11 <a href="http://www.blogjava.net/wash/archive/2005/12/26/25455.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cherrypy documentation</title><link>http://www.blogjava.net/wash/archive/2005/12/26/25405.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Mon, 26 Dec 2005 01:02:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2005/12/26/25405.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/25405.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2005/12/26/25405.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/25405.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/25405.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: .&nbsp;Application developer referenceAbstractCherryPy lets developers use Python to develop web applications, just as they would use Python for any other type of application. Building a web appli...&nbsp;&nbsp;<a href='http://www.blogjava.net/wash/archive/2005/12/26/25405.html'>阅读全文</a><img src ="http://www.blogjava.net/wash/aggbug/25405.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2005-12-26 09:02 <a href="http://www.blogjava.net/wash/archive/2005/12/26/25405.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>turbo gears get start</title><link>http://www.blogjava.net/wash/archive/2005/12/21/24908.html</link><dc:creator>wash</dc:creator><author>wash</author><pubDate>Wed, 21 Dec 2005 01:24:00 GMT</pubDate><guid>http://www.blogjava.net/wash/archive/2005/12/21/24908.html</guid><wfw:comment>http://www.blogjava.net/wash/comments/24908.html</wfw:comment><comments>http://www.blogjava.net/wash/archive/2005/12/21/24908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wash/comments/commentRss/24908.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wash/services/trackbacks/24908.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Your model objects represent the data that your application is working with. Your controller pulls in information coming from the user's web browser. It uses that information to update information i...&nbsp;&nbsp;<a href='http://www.blogjava.net/wash/archive/2005/12/21/24908.html'>阅读全文</a><img src ="http://www.blogjava.net/wash/aggbug/24908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wash/" target="_blank">wash</a> 2005-12-21 09:24 <a href="http://www.blogjava.net/wash/archive/2005/12/21/24908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>