comparison doc/text-templates.txt @ 241:4d81439bc097 trunk

* 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 fa07ab5a7e53
comparison
equal deleted inserted replaced
240:37039af315da 241:4d81439bc097
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.
Copyright (C) 2012-2017 Edgewall Software