annotate doc/templates.txt @ 500:0742f421caba experimental-inline

Merged revisions 487-603 via svnmerge from http://svn.edgewall.org/repos/genshi/trunk
author cmlenz
date Fri, 01 Jun 2007 17:21:47 +0000
parents
children 1837f39efd6f
rev   line source
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
1 .. -*- mode: rst; encoding: utf-8 -*-
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
2
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
3 ========================
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
4 Genshi Templating Basics
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
5 ========================
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
6
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
7 Genshi provides a template engine that can be used for generating either
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
8 markup (such as HTML_ or XML_) or plain text. While both share some of the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
9 syntax (and much of the underlying implementation) they are essentially
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
10 separate languages.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
11
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
12 .. _html: http://www.w3.org/html/
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
13 .. _xml: http://www.w3.org/XML/
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
14
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
15 This document describes the common parts of the template engine and will be most
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
16 useful as reference to those developing Genshi templates. Templates are XML or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
17 plain text files that include processing directives_ that affect how the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
18 template is rendered, and template expressions_ that are dynamically substituted
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
19 by variable data.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
20
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
21
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
22 .. contents:: Contents
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
23 :depth: 3
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
24 .. sectnum::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
25
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
26 --------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
27 Synopsis
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
28 --------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
29
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
30 A Genshi *markup template* is a well-formed XML document with embedded Python
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
31 used for control flow and variable substitution. Markup templates should be
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
32 used to generate any kind of HTML or XML output, as they provide many advantages
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
33 over simple text-based templates (such as automatic escaping of strings).
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
34
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
35 The following illustrates a very basic Genshi markup template::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
36
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
37 <?python
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
38 title = "A Genshi Template"
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
39 fruits = ["apple", "orange", "kiwi"]
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
40 ?>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
41 <html xmlns:py="http://genshi.edgewall.org/">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
42 <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
43 <title py:content="title">This is replaced.</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
44 </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
45
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
46 <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
47 <p>These are some of my favorite fruits:</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
48 <ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
49 <li py:for="fruit in fruits">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
50 I like ${fruit}s
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
51 </li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
52 </ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
53 </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
54 </html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
55
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
56 This example shows:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
57
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
58 (a) a Python code block, using a processing instruction
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
59 (b) the Genshi namespace declaration
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
60 (c) usage of templates directives (``py:content`` and ``py:for``)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
61 (d) an inline Python expression (``${fruit}``).
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
62
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
63 The template would generate output similar to this::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
64
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
65 <html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
66 <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
67 <title>A Genshi Template</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
68 </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
69
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
70 <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
71 <p>These are some of my favorite fruits:</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
72 <ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
73 <li>I like apples</li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
74 <li>I like oranges</li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
75 <li>I like kiwis</li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
76 </ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
77 </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
78 </html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
79
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
80 A *text template* is a simple plain text document that can also contain embedded
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
81 Python code. Text templates can be used to generate simple *non-markup* text
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
82 formats, such as the body of an plain text email. For example::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
83
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
84 Dear $name,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
85
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
86 These are some of my favorite fruits:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
87 #for fruit in fruits
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
88 * $fruit
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
89 #end
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
90
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
91
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
92 ----------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
93 Python API
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
94 ----------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
95
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
96 The Python code required for templating with Genshi is generally based on the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
97 following pattern:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
98
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
99 * Attain a ``MarkupTemplate`` or ``TextTemplate`` object from a string or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
100 file-like object containing the template source. This can either be done
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
101 directly, or through a ``TemplateLoader`` instance.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
102 * Call the ``generate()`` method of the template, passing any data that should
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
103 be made available to the template as keyword arguments.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
104 * Serialize the resulting stream using its ``render()`` method.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
105
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
106 For example::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
107
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
108 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
109 >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
110 >>> stream = tmpl.generate(name='world')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
111 >>> print stream.render()
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
112 <h1>Hello, world!</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
113
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
114 Using a text template is similar::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
115
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
116 >>> from genshi.template import TextTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
117 >>> tmpl = TextTemplate('Hello, $name!')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
118 >>> stream = tmpl.generate(name='world')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
119 >>> print stream.render()
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
120 Hello, world!
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
121
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
122 .. note:: See the Serialization_ section of the `Markup Streams`_ page for
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
123 information on configuring template output options.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
124
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
125 .. _serialization: streams.html#serialization
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
126 .. _`Markup Streams`: streams.html
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
127
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
128 Using a template loader provides the advantage that “compiled” templates are
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
129 automatically cached, and only parsed again when the template file changes. In
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
130 addition, it enables the use of a *template search path*, allowing template
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
131 directories to be spread across different file-system locations. Using a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
132 template loader would generally look as follows::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
133
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
134 from genshi.template import TemplateLoader
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
135 loader = TemplateLoader([templates_dir1, templates_dir2])
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
136 tmpl = loader.load('test.html')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
137 stream = tmpl.generate(title='Hello, world!')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
138 print stream.render()
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
139
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
140 See the `API documentation <api/index.html>`_ for details on using Genshi via
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
141 the Python API.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
142
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
143
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
144 .. _`expressions`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
145
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
146 ------------------------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
147 Template Expressions and Code Blocks
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
148 ------------------------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
149
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
150 Python_ expressions can be used in text and directive arguments. An expression
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
151 is substituted with the result of its evaluation against the template data.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
152 Expressions in text (which includes the values of non-directive attributes) need
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
153 to prefixed with a dollar sign (``$``) and usually enclosed in curly braces
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
154 (``{…}``).
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
155
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
156 .. _python: http://www.python.org/
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
157
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
158 If the expression starts with a letter and contains only letters, digits, dots,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
159 and underscores, the curly braces may be omitted. In all other cases, the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
160 braces are required so that the template processor knows where the expression
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
161 ends::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
162
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
163 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
164 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
165 >>> print tmpl.generate(items=['first', 'second'])
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
166 <em>First item</em>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
167
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
168 Expressions support the full power of Python. In addition, it is possible to
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
169 access items in a dictionary using “dotted notation” (i.e. as if they were
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
170 attributes), and vice-versa (i.e. access attributes as if they were items in a
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
171 dictionary)::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
172
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
173 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
174 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
175 >>> print tmpl.generate(dict={'foo': 'bar'})
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
176 <em>bar</em>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
177
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
178 Because there are two ways to access either attributes or items, expressions
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
179 do not raise the standard ``AttributeError`` or ``IndexError`` exceptions, but
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
180 rather an exception of the type ``UndefinedError``. The same kind of error is
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
181 raised when you try to use a top-level variable that is not in the context data.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
182 See `Error Handling`_ below for details on how such errors are handled.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
183
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
184
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
185 .. _`code blocks`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
186
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
187 Code Blocks
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
188 ===========
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
189
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
190 XML templates also support full Python code blocks using the ``<?python ?>``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
191 processing instruction::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
192
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
193 <div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
194 <?python
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
195 from genshi.builder import tag
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
196 def greeting(name):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
197 return tag.b('Hello, %s!' % name') ?>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
198 ${greeting('world')}
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
199 </div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
200
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
201 This will produce the following output::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
202
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
203 <div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
204 <b>Hello, world!</b>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
205 </div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
206
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
207 Code blocks can import modules, define classes and functions, and basically do
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
208 anything you can do in normal Python code. What code blocks can *not* do is to
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
209 produce content that is included directly in the generated page.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
210
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
211 .. note:: Using the ``print`` statement will print to the standard output
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
212 stream, just as it does for other Python code in your application.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
213
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
214 Unlike expressions, Python code in ``<?python ?>`` processing instructions can
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
215 not use item and attribute access in an interchangeable manner. That means that
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
216 “dotted notation” is always attribute access, and vice-versa.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
217
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
218 The support for Python code blocks in templates is not supposed to encourage
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
219 mixing application code into templates, which is generally considered bad
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
220 design. If you're using many code blocks, that may be a sign that you should
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
221 move such code into separate Python modules.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
222
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
223 .. note:: Code blocks are not currently supported in text templates.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
224
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
225
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
226 .. _`error handling`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
227
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
228 Error Handling
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
229 ==============
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
230
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
231 By default, Genshi allows you to access variables that are not defined, without
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
232 raising a ``NameError`` exception as regular Python code would::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
233
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
234 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
235 >>> tmpl = MarkupTemplate('<p>${doh}</p>')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
236 >>> print tmpl.generate().render('xhtml')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
237 <p></p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
238
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
239 You *will* however get an exception if you try to call an undefined variable, or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
240 do anything else with it, such as accessing its attributes::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
241
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
242 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
243 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
244 >>> print tmpl.generate().render('xhtml')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
245 Traceback (most recent call last):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
246 ...
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
247 UndefinedError: "doh" not defined
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
248
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
249 If you need to know whether a variable is defined, you can check its type
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
250 against the ``Undefined`` class, for example in a conditional directive::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
251
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
252 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
253 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
254 >>> print tmpl.generate().render('xhtml')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
255 <p>False</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
256
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
257 Alternatively, the built-in functions defined_ or value_of_ can be used in this
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
258 case.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
259
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
260 Strict Mode
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
261 -----------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
262
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
263 In addition to the default "lenient" error handling, Genshi lets you use a less
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
264 forgiving mode if you prefer errors blowing up loudly instead of being ignored
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
265 silently.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
266
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
267 This mode can be chosen by passing the ``lookup='strict'`` keyword argument to
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
268 the template initializer, or by passing the ``variable_lookup='strict'`` keyword
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
269 argument to the ``TemplateLoader`` initializer::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
270
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
271 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
272 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='strict')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
273 >>> print tmpl.generate().render('xhtml')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
274 Traceback (most recent call last):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
275 ...
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
276 UndefinedError: "doh" not defined
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
277
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
278 When using strict mode, any reference to an undefined variable, as well as
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
279 trying to access an non-existing item or attribute of an object, will cause an
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
280 ``UndefinedError`` to be raised immediately.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
281
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
282 .. note:: While this mode is currently not the default, it may be promoted to
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
283 the default in future versions of Genshi. In general, the default
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
284 lenient error handling mode can be considered dangerous as it silently
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
285 ignores typos.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
286
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
287 Custom Modes
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
288 ------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
289
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
290 In addition to the built-in "lenient" and "strict" modes, it is also possible to
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
291 use a custom error handling mode. For example, you could use lenient error
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
292 handling in a production environment, while also logging a warning when an
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
293 undefined variable is referenced.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
294
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
295 See the API documentation of the ``genshi.template.eval`` module for details.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
296
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
297
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
298 Built-in Functions & Types
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
299 ==========================
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
300
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
301 The following functions and types are available by default in template code, in
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
302 addition to the standard built-ins that are available to all Python code.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
303
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
304 .. _`defined`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
305
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
306 ``defined(name)``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
307 -----------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
308 This function determines whether a variable of the specified name exists in
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
309 the context data, and returns ``True`` if it does.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
310
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
311 .. _`value_of`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
312
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
313 ``value_of(name, default=None)``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
314 --------------------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
315 This function returns the value of the variable with the specified name if
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
316 such a variable is defined, and returns the value of the ``default``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
317 parameter if no such variable is defined.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
318
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
319 .. _`Markup`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
320
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
321 ``Markup(text)``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
322 ----------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
323 The ``Markup`` type marks a given string as being safe for inclusion in markup,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
324 meaning it will *not* be escaped in the serialization stage. Use this with care,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
325 as not escaping a user-provided string may allow malicious users to open your
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
326 web site to cross-site scripting attacks.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
327
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
328 .. _`Undefined`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
329
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
330 ``Undefined``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
331 ----------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
332 The ``Undefined`` type can be used to check whether a reference variable is
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
333 defined, as explained in `error handling`_.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
334
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
335
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
336 .. _`directives`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
337
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
338 -------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
339 Template Directives
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
340 -------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
341
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
342 Directives provide control flow functionality for templates, such as conditions
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
343 or iteration. As the syntax for directives depends on whether you're using
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
344 markup or text templates, refer to the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
345 `XML Template Language <xml-templates.html>`_ or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
346 `Text Template Language <text-templates.html>`_ pages for information.
Copyright (C) 2012-2017 Edgewall Software