Mercurial > genshi > genshi-test
comparison doc/templates.txt @ 902:09cc3627654c experimental-inline
Sync `experimental/inline` branch with [source:trunk@1126].
author | cmlenz |
---|---|
date | Fri, 23 Apr 2010 21:08:26 +0000 |
parents | 1837f39efd6f |
children |
comparison
equal
deleted
inserted
replaced
830:de82830f8816 | 902:09cc3627654c |
---|---|
27 Synopsis | 27 Synopsis |
28 -------- | 28 -------- |
29 | 29 |
30 A Genshi *markup template* is a well-formed XML document with embedded Python | 30 A Genshi *markup template* is a well-formed XML document with embedded Python |
31 used for control flow and variable substitution. Markup templates should be | 31 used for control flow and variable substitution. Markup templates should be |
32 used to generate any kind of HTML or XML output, as they provide many advantages | 32 used to generate any kind of HTML or XML output, as they provide a number of |
33 over simple text-based templates (such as automatic escaping of strings). | 33 advantages over simple text-based templates (such as automatic escaping of |
34 | 34 variable data). |
35 The following illustrates a very basic Genshi markup template: | 35 |
36 The following is a simple Genshi markup template: | |
36 | 37 |
37 .. code-block:: genshi | 38 .. code-block:: genshi |
38 | 39 |
39 <?python | 40 <?python |
40 title = "A Genshi Template" | 41 title = "A Genshi Template" |
55 </body> | 56 </body> |
56 </html> | 57 </html> |
57 | 58 |
58 This example shows: | 59 This example shows: |
59 | 60 |
60 (a) a Python code block, using a processing instruction | 61 (a) a Python code block in a processing instruction |
61 (b) the Genshi namespace declaration | 62 (b) the Genshi namespace declaration |
62 (c) usage of templates directives (``py:content`` and ``py:for``) | 63 (c) usage of templates directives (``py:content`` and ``py:for``) |
63 (d) an inline Python expression (``${fruit}``). | 64 (d) an inline Python expression (``${fruit}``). |
64 | 65 |
65 The template would generate output similar to this: | 66 The template would generate output similar to this: |
79 <li>I like kiwis</li> | 80 <li>I like kiwis</li> |
80 </ul> | 81 </ul> |
81 </body> | 82 </body> |
82 </html> | 83 </html> |
83 | 84 |
84 A *text template* is a simple plain text document that can also contain embedded | 85 A *text template* is a simple plain text document that can also contain |
85 Python code. Text templates can be used to generate simple *non-markup* text | 86 embedded Python code. Text templates are intended to be used for simple |
86 formats, such as the body of an plain text email. For example: | 87 *non-markup* text formats, such as the body of an plain text email. For |
88 example: | |
87 | 89 |
88 .. code-block:: genshitext | 90 .. code-block:: genshitext |
89 | 91 |
90 Dear $name, | 92 Dear $name, |
91 | 93 |
114 .. code-block:: pycon | 116 .. code-block:: pycon |
115 | 117 |
116 >>> from genshi.template import MarkupTemplate | 118 >>> from genshi.template import MarkupTemplate |
117 >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>') | 119 >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>') |
118 >>> stream = tmpl.generate(name='world') | 120 >>> stream = tmpl.generate(name='world') |
119 >>> print stream.render('xhtml') | 121 >>> print(stream.render('xhtml')) |
120 <h1>Hello, world!</h1> | 122 <h1>Hello, world!</h1> |
121 | 123 |
122 .. note:: See the Serialization_ section of the `Markup Streams`_ page for | 124 .. note:: See the Serialization_ section of the `Markup Streams`_ page for |
123 information on configuring template output options. | 125 information on configuring template output options. |
124 | 126 |
127 .. code-block:: pycon | 129 .. code-block:: pycon |
128 | 130 |
129 >>> from genshi.template import TextTemplate | 131 >>> from genshi.template import TextTemplate |
130 >>> tmpl = TextTemplate('Hello, $name!') | 132 >>> tmpl = TextTemplate('Hello, $name!') |
131 >>> stream = tmpl.generate(name='world') | 133 >>> stream = tmpl.generate(name='world') |
132 >>> print stream | 134 >>> print(stream) |
133 Hello, world! | 135 Hello, world! |
134 | 136 |
135 .. note:: If you want to use text templates, you should consider using the | 137 .. note:: If you want to use text templates, you should consider using the |
136 ``NewTextTemplate`` class instead of simply ``TextTemplate``. See | 138 ``NewTextTemplate`` class instead of simply ``TextTemplate``. See |
137 the `Text Template Language`_ page. | 139 the `Text Template Language`_ page. |
138 | 140 |
139 .. _serialization: streams.html#serialization | 141 .. _serialization: streams.html#serialization |
140 .. _`Text Template Language`: text-templates.html | 142 .. _`Text Template Language`: text-templates.html |
141 .. _`Markup Streams`: streams.html | 143 .. _`Markup Streams`: streams.html |
142 | 144 |
143 Using a template loader provides the advantage that “compiled” templates are | 145 Using a `template loader`_ provides the advantage that “compiled” templates are |
144 automatically cached, and only parsed again when the template file changes. In | 146 automatically cached, and only parsed again when the template file changes. In |
145 addition, it enables the use of a *template search path*, allowing template | 147 addition, it enables the use of a *template search path*, allowing template |
146 directories to be spread across different file-system locations. Using a | 148 directories to be spread across different file-system locations. Using a |
147 template loader would generally look as follows: | 149 template loader would generally look as follows: |
148 | 150 |
150 | 152 |
151 from genshi.template import TemplateLoader | 153 from genshi.template import TemplateLoader |
152 loader = TemplateLoader([templates_dir1, templates_dir2]) | 154 loader = TemplateLoader([templates_dir1, templates_dir2]) |
153 tmpl = loader.load('test.html') | 155 tmpl = loader.load('test.html') |
154 stream = tmpl.generate(title='Hello, world!') | 156 stream = tmpl.generate(title='Hello, world!') |
155 print stream.render() | 157 print(stream.render()) |
156 | 158 |
157 See the `API documentation <api/index.html>`_ for details on using Genshi via | 159 See the `API documentation <api/index.html>`_ for details on using Genshi via |
158 the Python API. | 160 the Python API. |
159 | 161 |
162 .. _`template loader`: loader.html | |
160 | 163 |
161 .. _`expressions`: | 164 .. _`expressions`: |
162 | 165 |
163 ------------------------------------ | 166 ------------------------------------ |
164 Template Expressions and Code Blocks | 167 Template Expressions and Code Blocks |
179 | 182 |
180 .. code-block:: pycon | 183 .. code-block:: pycon |
181 | 184 |
182 >>> from genshi.template import MarkupTemplate | 185 >>> from genshi.template import MarkupTemplate |
183 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>') | 186 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>') |
184 >>> print tmpl.generate(items=['first', 'second']) | 187 >>> print(tmpl.generate(items=['first', 'second'])) |
185 <em>First item</em> | 188 <em>First item</em> |
186 | 189 |
187 Expressions support the full power of Python. In addition, it is possible to | 190 Expressions support the full power of Python. In addition, it is possible to |
188 access items in a dictionary using “dotted notation” (i.e. as if they were | 191 access items in a dictionary using “dotted notation” (i.e. as if they were |
189 attributes), and vice-versa (i.e. access attributes as if they were items in a | 192 attributes), and vice-versa (i.e. access attributes as if they were items in a |
191 | 194 |
192 .. code-block:: pycon | 195 .. code-block:: pycon |
193 | 196 |
194 >>> from genshi.template import MarkupTemplate | 197 >>> from genshi.template import MarkupTemplate |
195 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>') | 198 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>') |
196 >>> print tmpl.generate(dict={'foo': 'bar'}) | 199 >>> print(tmpl.generate(dict={'foo': 'bar'})) |
197 <em>bar</em> | 200 <em>bar</em> |
198 | 201 |
199 Because there are two ways to access either attributes or items, expressions | 202 Because there are two ways to access either attributes or items, expressions |
200 do not raise the standard ``AttributeError`` or ``IndexError`` exceptions, but | 203 do not raise the standard ``AttributeError`` or ``IndexError`` exceptions, but |
201 rather an exception of the type ``UndefinedError``. The same kind of error is | 204 rather an exception of the type ``UndefinedError``. The same kind of error is |
211 | 214 |
212 .. code-block:: pycon | 215 .. code-block:: pycon |
213 | 216 |
214 >>> from genshi.template import MarkupTemplate | 217 >>> from genshi.template import MarkupTemplate |
215 >>> tmpl = MarkupTemplate('<em>$foo</em>') # Wanted "$foo" as literal output | 218 >>> tmpl = MarkupTemplate('<em>$foo</em>') # Wanted "$foo" as literal output |
216 >>> print tmpl.generate() | 219 >>> print(tmpl.generate()) |
217 Traceback (most recent call last): | 220 Traceback (most recent call last): |
218 ... | 221 ... |
219 UndefinedError: "foo" not defined | 222 UndefinedError: "foo" not defined |
220 >>> tmpl = MarkupTemplate('<em>$$foo</em>') | 223 >>> tmpl = MarkupTemplate('<em>$$foo</em>') |
221 >>> print tmpl.generate() | 224 >>> print(tmpl.generate()) |
222 <em>$foo</em> | 225 <em>$foo</em> |
223 | 226 |
224 But note that this is not necessary if the characters following the dollar sign | 227 But note that this is not necessary if the characters following the dollar sign |
225 do not qualify as an expression. For example, the following needs no escaping: | 228 do not qualify as an expression. For example, the following needs no escaping: |
226 | 229 |
227 .. code-block:: pycon | 230 .. code-block:: pycon |
228 | 231 |
229 >>> tmpl = MarkupTemplate('<script>$(function() {})</script>') | 232 >>> tmpl = MarkupTemplate('<script>$(function() {})</script>') |
230 >>> print tmpl.generate() | 233 >>> print(tmpl.generate()) |
231 <script>$(function() {})</script> | 234 <script>$(function() {})</script> |
232 | 235 |
233 On the other hand, Genshi will always replace two dollar signs in text with a | 236 On the other hand, Genshi will always replace two dollar signs in text with a |
234 single dollar sign, so you'll need to use three dollar signs to get two in the | 237 single dollar sign, so you'll need to use three dollar signs to get two in the |
235 output: | 238 output: |
236 | 239 |
237 .. code-block:: pycon | 240 .. code-block:: pycon |
238 | 241 |
239 >>> tmpl = MarkupTemplate('<script>$$$("div")</script>') | 242 >>> tmpl = MarkupTemplate('<script>$$$("div")</script>') |
240 >>> print tmpl.generate() | 243 >>> print(tmpl.generate()) |
241 <script>$$("div")</script> | 244 <script>$$("div")</script> |
242 | 245 |
243 | 246 |
244 .. _`code blocks`: | 247 .. _`code blocks`: |
245 | 248 |
336 ``getattr()`` or ``get()`` functions, or the ``in`` operator, just as you would | 339 ``getattr()`` or ``get()`` functions, or the ``in`` operator, just as you would |
337 in regular Python code: | 340 in regular Python code: |
338 | 341 |
339 >>> from genshi.template import MarkupTemplate | 342 >>> from genshi.template import MarkupTemplate |
340 >>> tmpl = MarkupTemplate('<p>${defined("doh")}</p>') | 343 >>> tmpl = MarkupTemplate('<p>${defined("doh")}</p>') |
341 >>> print tmpl.generate().render('xhtml') | 344 >>> print(tmpl.generate().render('xhtml')) |
342 <p>False</p> | 345 <p>False</p> |
343 | 346 |
344 .. note:: Lenient error handling was the default in Genshi prior to version 0.5. | 347 .. note:: Lenient error handling was the default in Genshi prior to version 0.5. |
345 Strict mode was introduced in version 0.4, and became the default in | 348 Strict mode was introduced in version 0.4, and became the default in |
346 0.5. The reason for this change was that the lenient error handling | 349 0.5. The reason for this change was that the lenient error handling |
362 | 365 |
363 .. code-block:: pycon | 366 .. code-block:: pycon |
364 | 367 |
365 >>> from genshi.template import MarkupTemplate | 368 >>> from genshi.template import MarkupTemplate |
366 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='lenient') | 369 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='lenient') |
367 >>> print tmpl.generate().render('xhtml') | 370 >>> print(tmpl.generate().render('xhtml')) |
368 <p></p> | 371 <p></p> |
369 | 372 |
370 You *will* however get an exception if you try to call an undefined variable, or | 373 You *will* however get an exception if you try to call an undefined variable, or |
371 do anything else with it, such as accessing its attributes: | 374 do anything else with it, such as accessing its attributes: |
372 | 375 |
373 .. code-block:: pycon | 376 .. code-block:: pycon |
374 | 377 |
375 >>> from genshi.template import MarkupTemplate | 378 >>> from genshi.template import MarkupTemplate |
376 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>', lookup='lenient') | 379 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>', lookup='lenient') |
377 >>> print tmpl.generate().render('xhtml') | 380 >>> print(tmpl.generate().render('xhtml')) |
378 Traceback (most recent call last): | 381 Traceback (most recent call last): |
379 ... | 382 ... |
380 UndefinedError: "doh" not defined | 383 UndefinedError: "doh" not defined |
381 | 384 |
382 If you need to know whether a variable is defined, you can check its type | 385 If you need to know whether a variable is defined, you can check its type |
385 .. code-block:: pycon | 388 .. code-block:: pycon |
386 | 389 |
387 >>> from genshi.template import MarkupTemplate | 390 >>> from genshi.template import MarkupTemplate |
388 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>', | 391 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>', |
389 ... lookup='lenient') | 392 ... lookup='lenient') |
390 >>> print tmpl.generate().render('xhtml') | 393 >>> print(tmpl.generate().render('xhtml')) |
391 <p>False</p> | 394 <p>False</p> |
392 | 395 |
393 Alternatively, the built-in functions defined_ or value_of_ can be used in this | 396 Alternatively, the built-in functions defined_ or value_of_ can be used in this |
394 case. | 397 case. |
395 | 398 |