annotate doc/templates.txt @ 821:f807fb8900ca experimental-inline

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