Mercurial > genshi > genshi-test
comparison doc/text-templates.txt @ 241:bbed6d426678
* Added basic documentation for the text-based template language.
* Directives in text templates are now closed with a simple `#end` line instead of the longer `#end<name>`.
author | cmlenz |
---|---|
date | Wed, 13 Sep 2006 14:52:58 +0000 |
parents | |
children | 78ae64ef822e |
comparison
equal
deleted
inserted
replaced
240:682471a23f5b | 241:bbed6d426678 |
---|---|
1 .. -*- mode: rst; encoding: utf-8 -*- | |
2 | |
3 ============================= | |
4 Genshi Text Template Language | |
5 ============================= | |
6 | |
7 In addition to the XML-based template language, Genshi provides a simple | |
8 text-based template language, intended for basic plain text generation needs. | |
9 The language is similar to Cheetah_ or Velocity_. | |
10 | |
11 .. _cheetah: http://cheetahtemplate.org/ | |
12 .. _velocity: http://jakarta.apache.org/velocity/ | |
13 | |
14 This document describes the template language and will be most useful as | |
15 reference to those developing Genshi text templates. Templates are XML files of some | |
16 kind (such as XHTML) that include processing directives_ (elements or | |
17 attributes identified by a separate namespace) that affect how the template is | |
18 rendered, and template expressions_ that are dynamically substituted by | |
19 variable data. | |
20 | |
21 | |
22 .. contents:: Contents | |
23 :depth: 3 | |
24 .. sectnum:: | |
25 | |
26 ---------- | |
27 Python API | |
28 ---------- | |
29 | |
30 The Python code required for templating with Genshi is generally based on the | |
31 following pattern: | |
32 | |
33 * Attain a ``Template`` object from a string or file object containing the | |
34 template source. This can either be done directly, or through a | |
35 ``TemplateLoader`` instance. | |
36 * Call the ``generate()`` method of the template, passing any data that should | |
37 be made available to the template as keyword arguments. | |
38 * Serialize the resulting stream using its ``render()`` method. | |
39 | |
40 For example:: | |
41 | |
42 from genshi.template import TextTemplate | |
43 | |
44 tmpl = TextTemplate('$title') | |
45 stream = tmpl.generate(title='Hello, world!') | |
46 print stream.render('text') | |
47 | |
48 That code would produce the following output:: | |
49 | |
50 Hello, world! | |
51 | |
52 Using a template loader provides the advantage that “compiled” templates are | |
53 automatically cached, and only parsed again when the template file changes:: | |
54 | |
55 from genshi.template import TemplateLoader | |
56 | |
57 loader = TemplateLoader([templates_dir]) | |
58 tmpl = loader.load('test.txt' cls=TextTemplate) | |
59 stream = tmpl.generate(title='Hello, world!') | |
60 print stream.render('text') | |
61 | |
62 | |
63 .. _`expressions`: | |
64 | |
65 -------------------- | |
66 Template Expressions | |
67 -------------------- | |
68 | |
69 Python_ expressions can be used in text and attribute values. An expression is | |
70 substituted with the result of its evaluation against the template data. | |
71 Expressions need to prefixed with a dollar sign (``$``) and usually enclosed in | |
72 curly braces (``{…}``). | |
73 | |
74 .. _python: http://www.python.org/ | |
75 | |
76 If the expression starts with a letter and contains only letters and digits, | |
77 the curly braces may be omitted. In all other cases, the braces are required | |
78 so that the template processors knows where the expression ends:: | |
79 | |
80 >>> from genshi.template import TextTemplate | |
81 >>> tmpl = TextTemplate('${items[0].capitalize()} item') | |
82 >>> print tmpl.generate(items=['first', 'second']) | |
83 First item | |
84 | |
85 Expressions support the full power of Python. In addition, it is possible to | |
86 access items in a dictionary using “dotted notation” (i.e. as if they were | |
87 attributes), and vice-versa (i.e. access attributes as if they were items in | |
88 a dictionary):: | |
89 | |
90 >>> from genshi.template import TextTemplate | |
91 >>> tmpl = TextTemplate('${dict.foo}') | |
92 >>> print tmpl.generate(dict={'foo': 'bar'}) | |
93 bar | |
94 | |
95 | |
96 .. _`directives`: | |
97 | |
98 ------------------- | |
99 Template Directives | |
100 ------------------- | |
101 | |
102 Directives are lines starting with a ``#`` character followed by the directive | |
103 name. They can affect how the template is rendered in a number of ways: Genshi | |
104 provides directives for conditionals and looping, among others. | |
105 | |
106 For example:: | |
107 | |
108 #if foo | |
109 Bar | |
110 #end | |
111 | |
112 Directives must be on separate lines, and the ``#`` character must be be the | |
113 first non-whitespace character on that line. Each directive must be “closed” | |
114 using a ``#end`` marker. | |
115 | |
116 | |
117 Conditional Sections | |
118 ==================== | |
119 | |
120 .. _`#if`: | |
121 | |
122 ``#if`` | |
123 --------- | |
124 | |
125 The content is only rendered if the expression evaluates to a truth value:: | |
126 | |
127 #if foo | |
128 ${bar} | |
129 #end | |
130 | |
131 Given the data ``foo=True`` and ``bar='Hello'`` in the template context, this | |
132 would produce:: | |
133 | |
134 Hello | |
135 | |
136 | |
137 .. _`#choose`: | |
138 .. _`#when`: | |
139 .. _`#otherwise`: | |
140 | |
141 ``#choose`` | |
142 ------------- | |
143 | |
144 The ``#choose`` directive, in combination with the directives ``#when`` and | |
145 ``#otherwise`` provides advanced contional processing for rendering one of | |
146 several alternatives. The first matching ``#when`` branch is rendered, or, if | |
147 no ``#when`` branch matches, the ``#otherwise`` branch is be rendered. | |
148 | |
149 If the ``#choose`` directive has no argument the nested ``#when`` directives | |
150 will be tested for truth:: | |
151 | |
152 The answer is: | |
153 #choose | |
154 #when 0 == 1 | |
155 0 | |
156 #end | |
157 #when 1 == 1 | |
158 1 | |
159 #end | |
160 #otherwise | |
161 2 | |
162 #end | |
163 #end | |
164 | |
165 This would produce the following output:: | |
166 | |
167 The answer is: | |
168 1 | |
169 | |
170 If the ``#choose`` does have an argument, the nested ``#when`` directives will | |
171 be tested for equality to the parent ``#choose`` value:: | |
172 | |
173 The answer is: | |
174 #choose 1 | |
175 #when 0 | |
176 0 | |
177 #end | |
178 #when 1 | |
179 1 | |
180 #end | |
181 #otherwise | |
182 2 | |
183 #end | |
184 #end | |
185 | |
186 This would produce the following output:: | |
187 | |
188 The answer is: | |
189 1 | |
190 | |
191 | |
192 Looping | |
193 ======= | |
194 | |
195 .. _`#for`: | |
196 | |
197 ``#for`` | |
198 ---------- | |
199 | |
200 The content is repeated for every item in an iterable:: | |
201 | |
202 Your items: | |
203 #for item in items | |
204 * ${item} | |
205 #end | |
206 | |
207 Given ``items=[1, 2, 3]`` in the context data, this would produce:: | |
208 | |
209 Your items | |
210 * 1 | |
211 * 2 | |
212 * 3 | |
213 | |
214 | |
215 Snippet Reuse | |
216 ============= | |
217 | |
218 .. _`#def`: | |
219 .. _`macros`: | |
220 | |
221 ``#def`` | |
222 ---------- | |
223 | |
224 The ``#def`` directive can be used to create macros, i.e. snippets of template | |
225 text that have a name and optionally some parameters, and that can be inserted | |
226 in other places:: | |
227 | |
228 #def greeting(name) | |
229 Hello, ${name}! | |
230 #end | |
231 ${greeting('world')} | |
232 ${greeting('everyone else')} | |
233 | |
234 The above would be rendered to:: | |
235 | |
236 Hello, world! | |
237 Hello, everyone else! | |
238 | |
239 If a macro doesn't require parameters, it can be defined as well as called | |
240 without the parenthesis. For example:: | |
241 | |
242 #def greeting | |
243 Hello, world! | |
244 #end | |
245 ${greeting} | |
246 | |
247 The above would be rendered to:: | |
248 | |
249 Hello, world! | |
250 | |
251 | |
252 Variable Binding | |
253 ================ | |
254 | |
255 .. _`#with`: | |
256 | |
257 ``#with`` | |
258 ----------- | |
259 | |
260 The ``#with`` directive lets you assign expressions to variables, which can | |
261 be used to make expressions inside the directive less verbose and more | |
262 efficient. For example, if you need use the expression ``author.posts`` more | |
263 than once, and that actually results in a database query, assigning the results | |
264 to a variable using this directive would probably help. | |
265 | |
266 For example:: | |
267 | |
268 Magic numbers! | |
269 #with y=7; z=x+10 | |
270 $x $y $z | |
271 #end | |
272 | |
273 Given ``x=42`` in the context data, this would produce:: | |
274 | |
275 Magic numbers! | |
276 42 7 52 | |
277 | |
278 Note that if a variable of the same name already existed outside of the scope | |
279 of the ``#with`` directive, it will **not** be overwritten. Instead, it will | |
280 have the same value it had prior to the ``#with`` assignment. Effectively, | |
281 this means that variables are immutable in Genshi. | |
282 | |
283 | |
284 .. _comments: | |
285 | |
286 -------- | |
287 Comments | |
288 -------- | |
289 | |
290 Lines where the first non-whitespace characters are ``##`` are removed from | |
291 the output, and can thus be used for comments. This can be escaped using a | |
292 backslash. |