annotate doc/templates.txt @ 902:09cc3627654c experimental-inline

Sync `experimental/inline` branch with [source:trunk@1126].
author cmlenz
date Fri, 23 Apr 2010 21:08:26 +0000
parents 1837f39efd6f
children
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
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
32 used to generate any kind of HTML or XML output, as they provide a number of
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
33 advantages over simple text-based templates (such as automatic escaping of
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
34 variable data).
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
35
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
36 The following is a simple Genshi markup template:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
37
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
38 .. code-block:: genshi
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
39
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
40 <?python
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
41 title = "A Genshi Template"
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
42 fruits = ["apple", "orange", "kiwi"]
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
43 ?>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
44 <html xmlns:py="http://genshi.edgewall.org/">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
45 <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
46 <title py:content="title">This is replaced.</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
47 </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
48
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
49 <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
50 <p>These are some of my favorite fruits:</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
51 <ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
52 <li py:for="fruit in fruits">
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
53 I like ${fruit}s
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
54 </li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
55 </ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
56 </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
57 </html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
58
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
59 This example shows:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
60
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
61 (a) a Python code block in a processing instruction
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
62 (b) the Genshi namespace declaration
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
63 (c) usage of templates directives (``py:content`` and ``py:for``)
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
64 (d) an inline Python expression (``${fruit}``).
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
65
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
66 The template would generate output similar to this:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
67
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
68 .. code-block:: genshi
500
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 <html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
71 <head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
72 <title>A Genshi Template</title>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
73 </head>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
74
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
75 <body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
76 <p>These are some of my favorite fruits:</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
77 <ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
78 <li>I like apples</li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
79 <li>I like oranges</li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
80 <li>I like kiwis</li>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
81 </ul>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
82 </body>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
83 </html>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
84
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
85 A *text template* is a simple plain text document that can also contain
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
86 embedded Python code. Text templates are intended to be used for simple
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
87 *non-markup* text formats, such as the body of an plain text email. For
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
88 example:
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
89
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
90 .. code-block:: genshitext
500
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 Dear $name,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
93
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
94 These are some of my favorite fruits:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
95 #for fruit in fruits
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
96 * $fruit
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
97 #end
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
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
100 ----------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
101 Python API
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
102 ----------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
103
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
104 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
105 following pattern:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
106
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
107 * Attain a ``MarkupTemplate`` or ``TextTemplate`` object from a string or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
108 file-like object containing the template source. This can either be done
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
109 directly, or through a ``TemplateLoader`` instance.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
110 * Call the ``generate()`` method of the template, passing any data that should
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
111 be made available to the template as keyword arguments.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
112 * Serialize the resulting stream using its ``render()`` method.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
113
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
114 For example:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
115
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
116 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
117
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
118 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
119 >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
120 >>> stream = tmpl.generate(name='world')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
121 >>> print(stream.render('xhtml'))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
122 <h1>Hello, world!</h1>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
123
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
124 .. note:: See the Serialization_ section of the `Markup Streams`_ page for
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
125 information on configuring template output options.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
126
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
127 Using a text template is similar:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
128
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
129 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
130
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
131 >>> from genshi.template import TextTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
132 >>> tmpl = TextTemplate('Hello, $name!')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
133 >>> stream = tmpl.generate(name='world')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
134 >>> print(stream)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
135 Hello, world!
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
136
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
137 .. note:: If you want to use text templates, you should consider using the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
138 ``NewTextTemplate`` class instead of simply ``TextTemplate``. See
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
139 the `Text Template Language`_ page.
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
140
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
141 .. _serialization: streams.html#serialization
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
142 .. _`Text Template Language`: text-templates.html
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
143 .. _`Markup Streams`: streams.html
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
144
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
145 Using a `template loader`_ provides the advantage that “compiled” templates are
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
146 automatically cached, and only parsed again when the template file changes. In
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
147 addition, it enables the use of a *template search path*, allowing template
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
148 directories to be spread across different file-system locations. Using a
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
149 template loader would generally look as follows:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
150
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
151 .. code-block:: python
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
152
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
153 from genshi.template import TemplateLoader
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
154 loader = TemplateLoader([templates_dir1, templates_dir2])
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
155 tmpl = loader.load('test.html')
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
156 stream = tmpl.generate(title='Hello, world!')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
157 print(stream.render())
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
158
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
159 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
160 the Python API.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
161
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
162 .. _`template loader`: loader.html
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
163
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
164 .. _`expressions`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
165
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
166 ------------------------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
167 Template Expressions and Code Blocks
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
168 ------------------------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
169
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
170 Python_ expressions can be used in text and directive arguments. An expression
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
171 is substituted with the result of its evaluation against the template data.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
172 Expressions in text (which includes the values of non-directive attributes) need
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
173 to prefixed with a dollar sign (``$``) and usually enclosed in curly braces
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
174 (``{…}``).
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
175
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
176 .. _python: http://www.python.org/
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 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
179 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
180 braces are required so that the template processor knows where the expression
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
181 ends:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
182
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
183 .. code-block:: pycon
500
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 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
186 >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
187 >>> print(tmpl.generate(items=['first', 'second']))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
188 <em>First item</em>
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 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
191 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
192 attributes), and vice-versa (i.e. access attributes as if they were items in a
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
193 dictionary):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
194
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
195 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
196
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
197 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
198 >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
199 >>> print(tmpl.generate(dict={'foo': 'bar'}))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
200 <em>bar</em>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
201
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
202 Because there are two ways to access either attributes or items, expressions
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
203 do not raise the standard ``AttributeError`` or ``IndexError`` exceptions, but
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
204 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
205 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
206 See `Error Handling`_ below for details on how such errors are handled.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
207
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
208
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
209 Escaping
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
210 ========
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
211
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
212 If you need to include a literal dollar sign in the output where Genshi would
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
213 normally detect an expression, you can simply add another dollar sign:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
214
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
215 .. code-block:: pycon
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
216
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
217 >>> from genshi.template import MarkupTemplate
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
218 >>> tmpl = MarkupTemplate('<em>$foo</em>') # Wanted "$foo" as literal output
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
219 >>> print(tmpl.generate())
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
220 Traceback (most recent call last):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
221 ...
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
222 UndefinedError: "foo" not defined
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
223 >>> tmpl = MarkupTemplate('<em>$$foo</em>')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
224 >>> print(tmpl.generate())
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
225 <em>$foo</em>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
226
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
227 But note that this is not necessary if the characters following the dollar sign
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
228 do not qualify as an expression. For example, the following needs no escaping:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
229
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
230 .. code-block:: pycon
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
231
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
232 >>> tmpl = MarkupTemplate('<script>$(function() {})</script>')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
233 >>> print(tmpl.generate())
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
234 <script>$(function() {})</script>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
235
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
236 On the other hand, Genshi will always replace two dollar signs in text with a
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
237 single dollar sign, so you'll need to use three dollar signs to get two in the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
238 output:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
239
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
240 .. code-block:: pycon
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
241
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
242 >>> tmpl = MarkupTemplate('<script>$$$("div")</script>')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
243 >>> print(tmpl.generate())
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
244 <script>$$("div")</script>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
245
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
246
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
247 .. _`code blocks`:
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 Code Blocks
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
250 ===========
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
251
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
252 Templates also support full Python code blocks, using the ``<?python ?>``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
253 processing instruction in XML templates:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
254
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
255 .. code-block:: genshi
500
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 <div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
258 <?python
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
259 from genshi.builder import tag
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
260 def greeting(name):
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
261 return tag.b('Hello, %s!' % name) ?>
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
262 ${greeting('world')}
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
263 </div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
264
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
265 This will produce the following output:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
266
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
267 .. code-block:: xml
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
268
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
269 <div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
270 <b>Hello, world!</b>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
271 </div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
272
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
273 In text templates (although only those using the new syntax introduced in
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
274 Genshi 0.5), code blocks use the special ``{% python %}`` directive:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
275
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
276 .. code-block:: genshitext
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
277
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
278 {% python
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
279 from genshi.builder import tag
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
280 def greeting(name):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
281 return 'Hello, %s!' % name
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
282 %}
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
283 ${greeting('world')}
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
284
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
285 This will produce the following output::
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
286
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
287 Hello, world!
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
288
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
289
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
290 Code blocks can import modules, define classes and functions, and basically do
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
291 anything you can do in normal Python code. What code blocks can *not* do is to
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
292 produce content that is emitted directly tp the generated output.
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
293
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
294 .. note:: Using the ``print`` statement will print to the standard output
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
295 stream, just as it does for other Python code in your application.
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 Unlike expressions, Python code in ``<?python ?>`` processing instructions can
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
298 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
299 “dotted notation” is always attribute access, and vice-versa.
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 support for Python code blocks in templates is not supposed to encourage
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
302 mixing application code into templates, which is generally considered bad
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
303 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
304 move such code into separate Python modules.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
305
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
306 If you'd rather not allow the use of Python code blocks in templates, you can
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
307 simply set the ``allow_exec`` parameter (available on the ``Template`` and the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
308 ``TemplateLoader`` initializers) to ``False``. In that case Genshi will raise
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
309 a syntax error when a ``<?python ?>`` processing instruction is encountered.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
310 But please note that disallowing code blocks in templates does not turn Genshi
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
311 into a sandboxable template engine; there are sufficient ways to do harm even
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
312 using plain expressions.
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
313
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 .. _`error handling`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
316
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
317 Error Handling
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
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
320 By default, Genshi raises an ``UndefinedError`` if a template expression
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
321 attempts to access a variable that is not defined:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
322
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
323 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
324
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
325 >>> from genshi.template import MarkupTemplate
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
326 >>> tmpl = MarkupTemplate('<p>${doh}</p>')
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
327 >>> tmpl.generate().render('xhtml')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
328 Traceback (most recent call last):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
329 ...
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
330 UndefinedError: "doh" not defined
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
331
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
332 You can change this behavior by setting the variable lookup mode to "lenient".
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
333 In that case, accessing undefined variables returns an `Undefined` object,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
334 meaning that the expression does not fail immediately. See below for details.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
335
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
336 If you need to check whether a variable exists in the template context, use the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
337 defined_ or the value_of_ function described below. To check for existence of
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
338 attributes on an object, or keys in a dictionary, use the ``hasattr()``,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
339 ``getattr()`` or ``get()`` functions, or the ``in`` operator, just as you would
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
340 in regular Python code:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
341
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
342 >>> from genshi.template import MarkupTemplate
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
343 >>> tmpl = MarkupTemplate('<p>${defined("doh")}</p>')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
344 >>> print(tmpl.generate().render('xhtml'))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
345 <p>False</p>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
346
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
347 .. note:: Lenient error handling was the default in Genshi prior to version 0.5.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
348 Strict mode was introduced in version 0.4, and became the default in
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
349 0.5. The reason for this change was that the lenient error handling
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
350 was masking actual errors in templates, thereby also making it harder
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
351 to debug some problems.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
352
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
353
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
354 .. _`lenient`:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
355
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
356 Lenient Mode
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
357 ------------
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
358
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
359 If you instruct Genshi to use the lenient variable lookup mode, it allows you
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
360 to access variables that are not defined, without raising an ``UndefinedError``.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
361
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
362 This mode can be chosen by passing the ``lookup='lenient'`` keyword argument to
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
363 the template initializer, or by passing the ``variable_lookup='lenient'``
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
364 keyword argument to the ``TemplateLoader`` initializer:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
365
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
366 .. code-block:: pycon
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
367
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
368 >>> from genshi.template import MarkupTemplate
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
369 >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='lenient')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
370 >>> print(tmpl.generate().render('xhtml'))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
371 <p></p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
372
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
373 You *will* however get an exception if you try to call an undefined variable, or
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
374 do anything else with it, such as accessing its attributes:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
375
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
376 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
377
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
378 >>> from genshi.template import MarkupTemplate
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
379 >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>', lookup='lenient')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
380 >>> print(tmpl.generate().render('xhtml'))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
381 Traceback (most recent call last):
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
382 ...
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
383 UndefinedError: "doh" not defined
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
384
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
385 If you need to know whether a variable is defined, you can check its type
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
386 against the ``Undefined`` class, for example in a conditional directive:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
387
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
388 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
389
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
390 >>> from genshi.template import MarkupTemplate
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
391 >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>',
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
392 ... lookup='lenient')
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
393 >>> print(tmpl.generate().render('xhtml'))
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
394 <p>False</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
395
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
396 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
397 case.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
398
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
399 Custom Modes
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
400 ------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
401
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
402 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
403 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
404 handling in a production environment, while also logging a warning when an
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
405 undefined variable is referenced.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
406
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
407 See the API documentation of the ``genshi.template.eval`` module for details.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
408
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
409
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
410 Built-in Functions & Types
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
411 ==========================
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
412
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
413 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
414 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
415
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
416 .. _`defined`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
417
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
418 ``defined(name)``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
419 -----------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
420 This function determines whether a variable of the specified name exists in
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
421 the context data, and returns ``True`` if it does.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
422
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
423 .. _`value_of`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
424
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
425 ``value_of(name, default=None)``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
426 --------------------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
427 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
428 such a variable is defined, and returns the value of the ``default``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
429 parameter if no such variable is defined.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
430
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
431 .. _`Markup`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
432
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
433 ``Markup(text)``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
434 ----------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
435 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
436 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
437 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
438 web site to cross-site scripting attacks.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
439
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
440 .. _`Undefined`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
441
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
442 ``Undefined``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
443 ----------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
444 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
445 defined, as explained in `error handling`_.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
446
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
447
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
448 .. _`directives`:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
449
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
450 -------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
451 Template Directives
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
452 -------------------
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
453
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
454 Directives provide control flow functionality for templates, such as conditions
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
455 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
456 markup or text templates, refer to the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
457 `XML Template Language <xml-templates.html>`_ or
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
458 `Text Template Language <text-templates.html>`_ pages for information.
Copyright (C) 2012-2017 Edgewall Software