Mercurial > genshi > genshi-test
comparison doc/templates.txt @ 510:ca7d707d51b0
Use syntax highlighting on all the other doc pages, too.
author | cmlenz |
---|---|
date | Wed, 06 Jun 2007 10:41:41 +0000 |
parents | 081c70ff7acd |
children | 6e21c89d9255 |
comparison
equal
deleted
inserted
replaced
509:1997f7af845c | 510:ca7d707d51b0 |
---|---|
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() |
112 <h1>Hello, world!</h1> | 120 <h1>Hello, world!</h1> |
113 | 121 |
114 Using a text template is similar:: | 122 Using a text template is similar: |
123 | |
124 .. code-block:: pycon | |
115 | 125 |
116 >>> from genshi.template import TextTemplate | 126 >>> from genshi.template import TextTemplate |
117 >>> tmpl = TextTemplate('Hello, $name!') | 127 >>> tmpl = TextTemplate('Hello, $name!') |
118 >>> stream = tmpl.generate(name='world') | 128 >>> stream = tmpl.generate(name='world') |
119 >>> print stream.render() | 129 >>> print stream.render() |
127 | 137 |
128 Using a template loader provides the advantage that “compiled” templates are | 138 Using a template loader provides the advantage that “compiled” templates are |
129 automatically cached, and only parsed again when the template file changes. In | 139 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 | 140 addition, it enables the use of a *template search path*, allowing template |
131 directories to be spread across different file-system locations. Using a | 141 directories to be spread across different file-system locations. Using a |
132 template loader would generally look as follows:: | 142 template loader would generally look as follows: |
143 | |
144 .. code-block:: python | |
133 | 145 |
134 from genshi.template import TemplateLoader | 146 from genshi.template import TemplateLoader |
135 loader = TemplateLoader([templates_dir1, templates_dir2]) | 147 loader = TemplateLoader([templates_dir1, templates_dir2]) |
136 tmpl = loader.load('test.html') | 148 tmpl = loader.load('test.html') |
137 stream = tmpl.generate(title='Hello, world!') | 149 stream = tmpl.generate(title='Hello, world!') |
156 .. _python: http://www.python.org/ | 168 .. _python: http://www.python.org/ |
157 | 169 |
158 If the expression starts with a letter and contains only letters, digits, dots, | 170 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 | 171 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 | 172 braces are required so that the template processor knows where the expression |
161 ends:: | 173 ends: |
174 | |
175 .. code-block:: pycon | |
162 | 176 |
163 >>> from genshi.template import MarkupTemplate | 177 >>> from genshi.template import MarkupTemplate |
164 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>') | 178 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>') |
165 >>> print tmpl.generate(items=['first', 'second']) | 179 >>> print tmpl.generate(items=['first', 'second']) |
166 <em>First item</em> | 180 <em>First item</em> |
167 | 181 |
168 Expressions support the full power of Python. In addition, it is possible to | 182 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 | 183 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 | 184 attributes), and vice-versa (i.e. access attributes as if they were items in a |
171 dictionary):: | 185 dictionary): |
186 | |
187 .. code-block:: pycon | |
172 | 188 |
173 >>> from genshi.template import MarkupTemplate | 189 >>> from genshi.template import MarkupTemplate |
174 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>') | 190 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>') |
175 >>> print tmpl.generate(dict={'foo': 'bar'}) | 191 >>> print tmpl.generate(dict={'foo': 'bar'}) |
176 <em>bar</em> | 192 <em>bar</em> |
186 | 202 |
187 Code Blocks | 203 Code Blocks |
188 =========== | 204 =========== |
189 | 205 |
190 XML templates also support full Python code blocks using the ``<?python ?>`` | 206 XML templates also support full Python code blocks using the ``<?python ?>`` |
191 processing instruction:: | 207 processing instruction: |
208 | |
209 .. code-block:: genshi | |
192 | 210 |
193 <div> | 211 <div> |
194 <?python | 212 <?python |
195 from genshi.builder import tag | 213 from genshi.builder import tag |
196 def greeting(name): | 214 def greeting(name): |
197 return tag.b('Hello, %s!' % name') ?> | 215 return tag.b('Hello, %s!' % name') ?> |
198 ${greeting('world')} | 216 ${greeting('world')} |
199 </div> | 217 </div> |
200 | 218 |
201 This will produce the following output:: | 219 This will produce the following output: |
220 | |
221 .. code-block:: genshi | |
202 | 222 |
203 <div> | 223 <div> |
204 <b>Hello, world!</b> | 224 <b>Hello, world!</b> |
205 </div> | 225 </div> |
206 | 226 |
227 | 247 |
228 Error Handling | 248 Error Handling |
229 ============== | 249 ============== |
230 | 250 |
231 By default, Genshi allows you to access variables that are not defined, without | 251 By default, Genshi allows you to access variables that are not defined, without |
232 raising a ``NameError`` exception as regular Python code would:: | 252 raising a ``NameError`` exception as regular Python code would: |
253 | |
254 .. code-block:: pycon | |
233 | 255 |
234 >>> from genshi.template import MarkupTemplate | 256 >>> from genshi.template import MarkupTemplate |
235 >>> tmpl = MarkupTemplate('<p>${doh}</p>') | 257 >>> tmpl = MarkupTemplate('<p>${doh}</p>') |
236 >>> print tmpl.generate().render('xhtml') | 258 >>> print tmpl.generate().render('xhtml') |
237 <p></p> | 259 <p></p> |
238 | 260 |
239 You *will* however get an exception if you try to call an undefined variable, or | 261 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:: | 262 do anything else with it, such as accessing its attributes: |
263 | |
264 .. code-block:: pycon | |
241 | 265 |
242 >>> from genshi.template import MarkupTemplate | 266 >>> from genshi.template import MarkupTemplate |
243 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>') | 267 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>') |
244 >>> print tmpl.generate().render('xhtml') | 268 >>> print tmpl.generate().render('xhtml') |
245 Traceback (most recent call last): | 269 Traceback (most recent call last): |
246 ... | 270 ... |
247 UndefinedError: "doh" not defined | 271 UndefinedError: "doh" not defined |
248 | 272 |
249 If you need to know whether a variable is defined, you can check its type | 273 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:: | 274 against the ``Undefined`` class, for example in a conditional directive: |
275 | |
276 .. code-block:: pycon | |
251 | 277 |
252 >>> from genshi.template import MarkupTemplate | 278 >>> from genshi.template import MarkupTemplate |
253 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>') | 279 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>') |
254 >>> print tmpl.generate().render('xhtml') | 280 >>> print tmpl.generate().render('xhtml') |
255 <p>False</p> | 281 <p>False</p> |
264 forgiving mode if you prefer errors blowing up loudly instead of being ignored | 290 forgiving mode if you prefer errors blowing up loudly instead of being ignored |
265 silently. | 291 silently. |
266 | 292 |
267 This mode can be chosen by passing the ``lookup='strict'`` keyword argument to | 293 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 | 294 the template initializer, or by passing the ``variable_lookup='strict'`` keyword |
269 argument to the ``TemplateLoader`` initializer:: | 295 argument to the ``TemplateLoader`` initializer: |
296 | |
297 .. code-block:: pycon | |
270 | 298 |
271 >>> from genshi.template import MarkupTemplate | 299 >>> from genshi.template import MarkupTemplate |
272 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='strict') | 300 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='strict') |
273 >>> print tmpl.generate().render('xhtml') | 301 >>> print tmpl.generate().render('xhtml') |
274 Traceback (most recent call last): | 302 Traceback (most recent call last): |