comparison doc/templates.txt @ 820:9755836bb396 experimental-inline

Sync (old) experimental inline branch with trunk@1027.
author cmlenz
date Wed, 11 Mar 2009 17:51:06 +0000
parents 3eb30e4ece8c
children fe25855324dd
comparison
equal deleted inserted replaced
500:3eb30e4ece8c 820:9755836bb396
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 many advantages
33 over simple text-based templates (such as automatic escaping of strings). 33 over simple text-based templates (such as automatic escaping of strings).
34 34
35 The following illustrates a very basic Genshi markup template:: 35 The following illustrates a very basic Genshi markup template:
36
37 .. code-block:: genshi
36 38
37 <?python 39 <?python
38 title = "A Genshi Template" 40 title = "A Genshi Template"
39 fruits = ["apple", "orange", "kiwi"] 41 fruits = ["apple", "orange", "kiwi"]
40 ?> 42 ?>
58 (a) a Python code block, using a processing instruction 60 (a) a Python code block, using a processing instruction
59 (b) the Genshi namespace declaration 61 (b) the Genshi namespace declaration
60 (c) usage of templates directives (``py:content`` and ``py:for``) 62 (c) usage of templates directives (``py:content`` and ``py:for``)
61 (d) an inline Python expression (``${fruit}``). 63 (d) an inline Python expression (``${fruit}``).
62 64
63 The template would generate output similar to this:: 65 The template would generate output similar to this:
66
67 .. code-block:: genshi
64 68
65 <html> 69 <html>
66 <head> 70 <head>
67 <title>A Genshi Template</title> 71 <title>A Genshi Template</title>
68 </head> 72 </head>
77 </body> 81 </body>
78 </html> 82 </html>
79 83
80 A *text template* is a simple plain text document that can also contain embedded 84 A *text template* is a simple plain text document that can also contain embedded
81 Python code. Text templates can be used to generate simple *non-markup* text 85 Python code. Text templates can be used to generate simple *non-markup* text
82 formats, such as the body of an plain text email. For example:: 86 formats, such as the body of an plain text email. For example:
87
88 .. code-block:: genshitext
83 89
84 Dear $name, 90 Dear $name,
85 91
86 These are some of my favorite fruits: 92 These are some of my favorite fruits:
87 #for fruit in fruits 93 #for fruit in fruits
101 directly, or through a ``TemplateLoader`` instance. 107 directly, or through a ``TemplateLoader`` instance.
102 * Call the ``generate()`` method of the template, passing any data that should 108 * Call the ``generate()`` method of the template, passing any data that should
103 be made available to the template as keyword arguments. 109 be made available to the template as keyword arguments.
104 * Serialize the resulting stream using its ``render()`` method. 110 * Serialize the resulting stream using its ``render()`` method.
105 111
106 For example:: 112 For example:
113
114 .. code-block:: pycon
107 115
108 >>> from genshi.template import MarkupTemplate 116 >>> from genshi.template import MarkupTemplate
109 >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>') 117 >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>')
110 >>> stream = tmpl.generate(name='world') 118 >>> stream = tmpl.generate(name='world')
111 >>> print stream.render() 119 >>> print stream.render('xhtml')
112 <h1>Hello, world!</h1> 120 <h1>Hello, world!</h1>
113 121
114 Using a text template is similar:: 122 .. note:: See the Serialization_ section of the `Markup Streams`_ page for
123 information on configuring template output options.
124
125 Using a text template is similar:
126
127 .. code-block:: pycon
115 128
116 >>> from genshi.template import TextTemplate 129 >>> from genshi.template import TextTemplate
117 >>> tmpl = TextTemplate('Hello, $name!') 130 >>> tmpl = TextTemplate('Hello, $name!')
118 >>> stream = tmpl.generate(name='world') 131 >>> stream = tmpl.generate(name='world')
119 >>> print stream.render() 132 >>> print stream
120 Hello, world! 133 Hello, world!
121 134
122 .. note:: See the Serialization_ section of the `Markup Streams`_ page for 135 .. note:: If you want to use text templates, you should consider using the
123 information on configuring template output options. 136 ``NewTextTemplate`` class instead of simply ``TextTemplate``. See
137 the `Text Template Language`_ page.
124 138
125 .. _serialization: streams.html#serialization 139 .. _serialization: streams.html#serialization
140 .. _`Text Template Language`: text-templates.html
126 .. _`Markup Streams`: streams.html 141 .. _`Markup Streams`: streams.html
127 142
128 Using a template loader provides the advantage that “compiled” templates are 143 Using a template loader provides the advantage that “compiled” templates are
129 automatically cached, and only parsed again when the template file changes. In 144 automatically cached, and only parsed again when the template file changes. In
130 addition, it enables the use of a *template search path*, allowing template 145 addition, it enables the use of a *template search path*, allowing template
131 directories to be spread across different file-system locations. Using a 146 directories to be spread across different file-system locations. Using a
132 template loader would generally look as follows:: 147 template loader would generally look as follows:
148
149 .. code-block:: python
133 150
134 from genshi.template import TemplateLoader 151 from genshi.template import TemplateLoader
135 loader = TemplateLoader([templates_dir1, templates_dir2]) 152 loader = TemplateLoader([templates_dir1, templates_dir2])
136 tmpl = loader.load('test.html') 153 tmpl = loader.load('test.html')
137 stream = tmpl.generate(title='Hello, world!') 154 stream = tmpl.generate(title='Hello, world!')
156 .. _python: http://www.python.org/ 173 .. _python: http://www.python.org/
157 174
158 If the expression starts with a letter and contains only letters, digits, dots, 175 If the expression starts with a letter and contains only letters, digits, dots,
159 and underscores, the curly braces may be omitted. In all other cases, the 176 and underscores, the curly braces may be omitted. In all other cases, the
160 braces are required so that the template processor knows where the expression 177 braces are required so that the template processor knows where the expression
161 ends:: 178 ends:
179
180 .. code-block:: pycon
162 181
163 >>> from genshi.template import MarkupTemplate 182 >>> from genshi.template import MarkupTemplate
164 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>') 183 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>')
165 >>> print tmpl.generate(items=['first', 'second']) 184 >>> print tmpl.generate(items=['first', 'second'])
166 <em>First item</em> 185 <em>First item</em>
167 186
168 Expressions support the full power of Python. In addition, it is possible to 187 Expressions support the full power of Python. In addition, it is possible to
169 access items in a dictionary using “dotted notation” (i.e. as if they were 188 access items in a dictionary using “dotted notation” (i.e. as if they were
170 attributes), and vice-versa (i.e. access attributes as if they were items in a 189 attributes), and vice-versa (i.e. access attributes as if they were items in a
171 dictionary):: 190 dictionary):
191
192 .. code-block:: pycon
172 193
173 >>> from genshi.template import MarkupTemplate 194 >>> from genshi.template import MarkupTemplate
174 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>') 195 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>')
175 >>> print tmpl.generate(dict={'foo': 'bar'}) 196 >>> print tmpl.generate(dict={'foo': 'bar'})
176 <em>bar</em> 197 <em>bar</em>
180 rather an exception of the type ``UndefinedError``. The same kind of error is 201 rather an exception of the type ``UndefinedError``. The same kind of error is
181 raised when you try to use a top-level variable that is not in the context data. 202 raised when you try to use a top-level variable that is not in the context data.
182 See `Error Handling`_ below for details on how such errors are handled. 203 See `Error Handling`_ below for details on how such errors are handled.
183 204
184 205
206 Escaping
207 ========
208
209 If you need to include a literal dollar sign in the output where Genshi would
210 normally detect an expression, you can simply add another dollar sign:
211
212 .. code-block:: pycon
213
214 >>> from genshi.template import MarkupTemplate
215 >>> tmpl = MarkupTemplate('<em>$foo</em>') # Wanted "$foo" as literal output
216 >>> print tmpl.generate()
217 Traceback (most recent call last):
218 ...
219 UndefinedError: "foo" not defined
220 >>> tmpl = MarkupTemplate('<em>$$foo</em>')
221 >>> print tmpl.generate()
222 <em>$foo</em>
223
224 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:
226
227 .. code-block:: pycon
228
229 >>> tmpl = MarkupTemplate('<script>$(function() {})</script>')
230 >>> print tmpl.generate()
231 <script>$(function() {})</script>
232
233 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
235 output:
236
237 .. code-block:: pycon
238
239 >>> tmpl = MarkupTemplate('<script>$$$("div")</script>')
240 >>> print tmpl.generate()
241 <script>$$("div")</script>
242
243
185 .. _`code blocks`: 244 .. _`code blocks`:
186 245
187 Code Blocks 246 Code Blocks
188 =========== 247 ===========
189 248
190 XML templates also support full Python code blocks using the ``<?python ?>`` 249 Templates also support full Python code blocks, using the ``<?python ?>``
191 processing instruction:: 250 processing instruction in XML templates:
251
252 .. code-block:: genshi
192 253
193 <div> 254 <div>
194 <?python 255 <?python
195 from genshi.builder import tag 256 from genshi.builder import tag
196 def greeting(name): 257 def greeting(name):
197 return tag.b('Hello, %s!' % name') ?> 258 return tag.b('Hello, %s!' % name) ?>
198 ${greeting('world')} 259 ${greeting('world')}
199 </div> 260 </div>
200 261
201 This will produce the following output:: 262 This will produce the following output:
263
264 .. code-block:: xml
202 265
203 <div> 266 <div>
204 <b>Hello, world!</b> 267 <b>Hello, world!</b>
205 </div> 268 </div>
206 269
270 In text templates (although only those using the new syntax introduced in
271 Genshi 0.5), code blocks use the special ``{% python %}`` directive:
272
273 .. code-block:: genshitext
274
275 {% python
276 from genshi.builder import tag
277 def greeting(name):
278 return 'Hello, %s!' % name
279 %}
280 ${greeting('world')}
281
282 This will produce the following output::
283
284 Hello, world!
285
286
207 Code blocks can import modules, define classes and functions, and basically do 287 Code blocks can import modules, define classes and functions, and basically do
208 anything you can do in normal Python code. What code blocks can *not* do is to 288 anything you can do in normal Python code. What code blocks can *not* do is to
209 produce content that is included directly in the generated page. 289 produce content that is emitted directly tp the generated output.
210 290
211 .. note:: Using the ``print`` statement will print to the standard output 291 .. note:: Using the ``print`` statement will print to the standard output
212 stream, just as it does for other Python code in your application. 292 stream, just as it does for other Python code in your application.
213 293
214 Unlike expressions, Python code in ``<?python ?>`` processing instructions can 294 Unlike expressions, Python code in ``<?python ?>`` processing instructions can
218 The support for Python code blocks in templates is not supposed to encourage 298 The support for Python code blocks in templates is not supposed to encourage
219 mixing application code into templates, which is generally considered bad 299 mixing application code into templates, which is generally considered bad
220 design. If you're using many code blocks, that may be a sign that you should 300 design. If you're using many code blocks, that may be a sign that you should
221 move such code into separate Python modules. 301 move such code into separate Python modules.
222 302
223 .. note:: Code blocks are not currently supported in text templates. 303 If you'd rather not allow the use of Python code blocks in templates, you can
304 simply set the ``allow_exec`` parameter (available on the ``Template`` and the
305 ``TemplateLoader`` initializers) to ``False``. In that case Genshi will raise
306 a syntax error when a ``<?python ?>`` processing instruction is encountered.
307 But please note that disallowing code blocks in templates does not turn Genshi
308 into a sandboxable template engine; there are sufficient ways to do harm even
309 using plain expressions.
224 310
225 311
226 .. _`error handling`: 312 .. _`error handling`:
227 313
228 Error Handling 314 Error Handling
229 ============== 315 ==============
230 316
231 By default, Genshi allows you to access variables that are not defined, without 317 By default, Genshi raises an ``UndefinedError`` if a template expression
232 raising a ``NameError`` exception as regular Python code would:: 318 attempts to access a variable that is not defined:
319
320 .. code-block:: pycon
233 321
234 >>> from genshi.template import MarkupTemplate 322 >>> from genshi.template import MarkupTemplate
235 >>> tmpl = MarkupTemplate('<p>${doh}</p>') 323 >>> tmpl = MarkupTemplate('<p>${doh}</p>')
324 >>> tmpl.generate().render('xhtml')
325 Traceback (most recent call last):
326 ...
327 UndefinedError: "doh" not defined
328
329 You can change this behavior by setting the variable lookup mode to "lenient".
330 In that case, accessing undefined variables returns an `Undefined` object,
331 meaning that the expression does not fail immediately. See below for details.
332
333 If you need to check whether a variable exists in the template context, use the
334 defined_ or the value_of_ function described below. To check for existence of
335 attributes on an object, or keys in a dictionary, use the ``hasattr()``,
336 ``getattr()`` or ``get()`` functions, or the ``in`` operator, just as you would
337 in regular Python code:
338
339 >>> from genshi.template import MarkupTemplate
340 >>> tmpl = MarkupTemplate('<p>${defined("doh")}</p>')
341 >>> print tmpl.generate().render('xhtml')
342 <p>False</p>
343
344 .. 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
346 0.5. The reason for this change was that the lenient error handling
347 was masking actual errors in templates, thereby also making it harder
348 to debug some problems.
349
350
351 .. _`lenient`:
352
353 Lenient Mode
354 ------------
355
356 If you instruct Genshi to use the lenient variable lookup mode, it allows you
357 to access variables that are not defined, without raising an ``UndefinedError``.
358
359 This mode can be chosen by passing the ``lookup='lenient'`` keyword argument to
360 the template initializer, or by passing the ``variable_lookup='lenient'``
361 keyword argument to the ``TemplateLoader`` initializer:
362
363 .. code-block:: pycon
364
365 >>> from genshi.template import MarkupTemplate
366 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='lenient')
236 >>> print tmpl.generate().render('xhtml') 367 >>> print tmpl.generate().render('xhtml')
237 <p></p> 368 <p></p>
238 369
239 You *will* however get an exception if you try to call an undefined variable, or 370 You *will* however get an exception if you try to call an undefined variable, or
240 do anything else with it, such as accessing its attributes:: 371 do anything else with it, such as accessing its attributes:
241 372
242 >>> from genshi.template import MarkupTemplate 373 .. code-block:: pycon
243 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>') 374
375 >>> from genshi.template import MarkupTemplate
376 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>', lookup='lenient')
244 >>> print tmpl.generate().render('xhtml') 377 >>> print tmpl.generate().render('xhtml')
245 Traceback (most recent call last): 378 Traceback (most recent call last):
246 ... 379 ...
247 UndefinedError: "doh" not defined 380 UndefinedError: "doh" not defined
248 381
249 If you need to know whether a variable is defined, you can check its type 382 If you need to know whether a variable is defined, you can check its type
250 against the ``Undefined`` class, for example in a conditional directive:: 383 against the ``Undefined`` class, for example in a conditional directive:
251 384
252 >>> from genshi.template import MarkupTemplate 385 .. code-block:: pycon
253 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>') 386
387 >>> from genshi.template import MarkupTemplate
388 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>',
389 ... lookup='lenient')
254 >>> print tmpl.generate().render('xhtml') 390 >>> print tmpl.generate().render('xhtml')
255 <p>False</p> 391 <p>False</p>
256 392
257 Alternatively, the built-in functions defined_ or value_of_ can be used in this 393 Alternatively, the built-in functions defined_ or value_of_ can be used in this
258 case. 394 case.
259
260 Strict Mode
261 -----------
262
263 In addition to the default "lenient" error handling, Genshi lets you use a less
264 forgiving mode if you prefer errors blowing up loudly instead of being ignored
265 silently.
266
267 This mode can be chosen by passing the ``lookup='strict'`` keyword argument to
268 the template initializer, or by passing the ``variable_lookup='strict'`` keyword
269 argument to the ``TemplateLoader`` initializer::
270
271 >>> from genshi.template import MarkupTemplate
272 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='strict')
273 >>> print tmpl.generate().render('xhtml')
274 Traceback (most recent call last):
275 ...
276 UndefinedError: "doh" not defined
277
278 When using strict mode, any reference to an undefined variable, as well as
279 trying to access an non-existing item or attribute of an object, will cause an
280 ``UndefinedError`` to be raised immediately.
281
282 .. note:: While this mode is currently not the default, it may be promoted to
283 the default in future versions of Genshi. In general, the default
284 lenient error handling mode can be considered dangerous as it silently
285 ignores typos.
286 395
287 Custom Modes 396 Custom Modes
288 ------------ 397 ------------
289 398
290 In addition to the built-in "lenient" and "strict" modes, it is also possible to 399 In addition to the built-in "lenient" and "strict" modes, it is also possible to
Copyright (C) 2012-2017 Edgewall Software