Mercurial > genshi > mirror
comparison doc/xml-templates.txt @ 500:3eb30e4ece8c experimental-inline
Merged revisions 487-603 via svnmerge from
http://svn.edgewall.org/repos/genshi/trunk
author | cmlenz |
---|---|
date | Fri, 01 Jun 2007 17:21:47 +0000 |
parents | a81675590258 |
children | 9755836bb396 |
comparison
equal
deleted
inserted
replaced
499:b2704e935eb2 | 500:3eb30e4ece8c |
---|---|
16 | 16 |
17 This document describes the template language and will be most useful as | 17 This document describes the template language and will be most useful as |
18 reference to those developing Genshi XML templates. Templates are XML files of | 18 reference to those developing Genshi XML templates. Templates are XML files of |
19 some kind (such as XHTML) that include processing directives_ (elements or | 19 some kind (such as XHTML) that include processing directives_ (elements or |
20 attributes identified by a separate namespace) that affect how the template is | 20 attributes identified by a separate namespace) that affect how the template is |
21 rendered, and template expressions_ that are dynamically substituted by | 21 rendered, and template expressions that are dynamically substituted by |
22 variable data. | 22 variable data. |
23 | |
24 See `Genshi Templating Basics <templates.html>`_ for general information on | |
25 embedding Python code in templates. | |
23 | 26 |
24 | 27 |
25 .. contents:: Contents | 28 .. contents:: Contents |
26 :depth: 3 | 29 :depth: 3 |
27 .. sectnum:: | 30 .. sectnum:: |
28 | |
29 ---------- | |
30 Python API | |
31 ---------- | |
32 | |
33 The Python code required for templating with Genshi is generally based on the | |
34 following pattern: | |
35 | |
36 * Attain a ``MarkupTemplate`` object from a string or file object containing | |
37 the template XML source. This can either be done directly, or through a | |
38 ``TemplateLoader`` instance. | |
39 * Call the ``generate()`` method of the template, passing any data that should | |
40 be made available to the template as keyword arguments. | |
41 * Serialize the resulting stream using its ``render()`` method. | |
42 | |
43 For example:: | |
44 | |
45 from genshi.template import MarkupTemplate | |
46 | |
47 tmpl = MarkupTemplate('<h1>$title</h1>') | |
48 stream = tmpl.generate(title='Hello, world!') | |
49 print stream.render('xhtml') | |
50 | |
51 That code would produce the following output:: | |
52 | |
53 <h1>Hello, world!</h1> | |
54 | |
55 However, if you want includes_ to work, you should attain the template instance | |
56 through a ``TemplateLoader``, and load the template from a file:: | |
57 | |
58 from genshi.template import TemplateLoader | |
59 | |
60 loader = TemplateLoader([templates_dir]) | |
61 tmpl = loader.load('test.html') | |
62 stream = tmpl.generate(title='Hello, world!') | |
63 print stream.render('xhtml') | |
64 | |
65 | |
66 .. _`expressions`: | |
67 | |
68 -------------------- | |
69 Template Expressions | |
70 -------------------- | |
71 | |
72 Python_ expressions can be used in text and attribute values. An expression is | |
73 substituted with the result of its evaluation against the template data. | |
74 Expressions need to prefixed with a dollar sign (``$``) and usually enclosed in | |
75 curly braces (``{…}``). | |
76 | |
77 If the expression starts with a letter and contains only letters, digits, dots, | |
78 and underscores, the curly braces may be omitted. In all other cases, the | |
79 braces are required so that the template processor knows where the expression | |
80 ends:: | |
81 | |
82 >>> from genshi.template import MarkupTemplate | |
83 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>') | |
84 >>> print tmpl.generate(items=['first', 'second']) | |
85 <em>First item</em> | |
86 | |
87 Expressions support the full power of Python. In addition, it is possible to | |
88 access items in a dictionary using “dotted notation” (i.e. as if they were | |
89 attributes), and vice-versa (i.e. access attributes as if they were items in a | |
90 dictionary):: | |
91 | |
92 >>> from genshi.template import MarkupTemplate | |
93 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>') | |
94 >>> print tmpl.generate(dict={'foo': 'bar'}) | |
95 <em>bar</em> | |
96 | |
97 Another difference is that you can access variables that are not defined, and | |
98 won't get a ``NameError`` exception:: | |
99 | |
100 >>> from genshi.template import TextTemplate | |
101 >>> tmpl = TextTemplate('${doh}') | |
102 >>> print tmpl.generate() | |
103 <BLANKLINE> | |
104 | |
105 You **will** however get a ``NameError`` if you try to call an undefined | |
106 variable, or do anything else with it, such as accessing its attributes. If you | |
107 need to know whether a variable is defined, you can check its type against the | |
108 ``Undefined`` class, for example in a `py:if`_ directive:: | |
109 | |
110 >>> from genshi.template import TextTemplate | |
111 >>> tmpl = TextTemplate('${type(doh) is Undefined}') | |
112 >>> print tmpl.generate() | |
113 True | |
114 | 31 |
115 | 32 |
116 .. _`directives`: | 33 .. _`directives`: |
117 | 34 |
118 ------------------- | 35 ------------------- |
205 | 122 |
206 ``py:choose`` | 123 ``py:choose`` |
207 ------------- | 124 ------------- |
208 | 125 |
209 The ``py:choose`` directive, in combination with the directives ``py:when`` | 126 The ``py:choose`` directive, in combination with the directives ``py:when`` |
210 and ``py:otherwise`` provides advanced contional processing for rendering one | 127 and ``py:otherwise`` provides advanced conditional processing for rendering one |
211 of several alternatives. The first matching ``py:when`` branch is rendered, or, | 128 of several alternatives. The first matching ``py:when`` branch is rendered, or, |
212 if no ``py:when`` branch matches, the ``py:otherwise`` branch is be rendered. | 129 if no ``py:when`` branch matches, the ``py:otherwise`` branch is rendered. |
213 | 130 |
214 If the ``py:choose`` directive is empty the nested ``py:when`` directives will | 131 If the ``py:choose`` directive is empty the nested ``py:when`` directives will |
215 be tested for truth:: | 132 be tested for truth:: |
216 | 133 |
217 <div py:choose=""> | 134 <div py:choose=""> |
358 </span> | 275 </span> |
359 </div> | 276 </div> |
360 | 277 |
361 Inside the body of a ``py:match`` directive, the ``select(path)`` function is | 278 Inside the body of a ``py:match`` directive, the ``select(path)`` function is |
362 made available so that parts or all of the original element can be incorporated | 279 made available so that parts or all of the original element can be incorporated |
363 in the output of the match template. See [wiki:GenshiStream#UsingXPath] for | 280 in the output of the match template. See `Using XPath`_ for more information |
364 more information about this function. | 281 about this function. |
282 | |
283 .. _`Using XPath`: streams.html#using-xpath | |
365 | 284 |
366 This directive can also be used as an element:: | 285 This directive can also be used as an element:: |
367 | 286 |
368 <div> | 287 <div> |
369 <py:match path="greeting"> | 288 <py:match path="greeting"> |
574 that Genshi currently only supports a small subset of XInclude. | 493 that Genshi currently only supports a small subset of XInclude. |
575 | 494 |
576 .. _`xinclude specification`: http://www.w3.org/TR/xinclude/ | 495 .. _`xinclude specification`: http://www.w3.org/TR/xinclude/ |
577 | 496 |
578 Incudes in Genshi are fully dynamic: Just like normal attributes, the `href` | 497 Incudes in Genshi are fully dynamic: Just like normal attributes, the `href` |
579 attribute accepts expressions_, and directives_ can be used on the | 498 attribute accepts expressions, and directives_ can be used on the |
580 ``<xi:include />`` element just as on any other element, meaning you can do | 499 ``<xi:include />`` element just as on any other element, meaning you can do |
581 things like conditional includes:: | 500 things like conditional includes:: |
582 | 501 |
583 <xi:include href="${name}.html" py:if="not in_popup" | 502 <xi:include href="${name}.html" py:if="not in_popup" |
584 py:for="name in ('foo', 'bar', 'baz')" /> | 503 py:for="name in ('foo', 'bar', 'baz')" /> |