annotate doc/filters.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 Stream Filters
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 `Markup Streams`_ showed how to write filters and how they are applied to
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
8 markup streams. This page describes the features of the various filters that
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
9 come with Genshi itself.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
10
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
11 .. _`Markup Streams`: streams.html
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
12
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
13 .. contents:: Contents
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
14 :depth: 1
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
15 .. sectnum::
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
16
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
17
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
18 HTML Form Filler
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
19 ================
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
20
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
21 The filter ``genshi.filters.html.HTMLFormFiller`` can automatically populate an
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
22 HTML form from values provided as a simple dictionary. When using this filter,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
23 you can basically omit any ``value``, ``selected``, or ``checked`` attributes
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
24 from form controls in your templates, and let the filter do all that work for
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
25 you.
500
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 ``HTMLFormFiller`` takes a dictionary of data to populate the form with, where
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
28 the keys should match the names of form elements, and the values determine the
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
29 values of those controls. For example:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
30
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
31 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
32
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
33 >>> from genshi.filters import HTMLFormFiller
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
34 >>> from genshi.template import MarkupTemplate
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
35
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
36 >>> template = MarkupTemplate("""<form>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
37 ... <p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
38 ... <label>User name:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
39 ... <input type="text" name="username" />
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
40 ... </label><br />
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
41 ... <label>Password:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
42 ... <input type="password" name="password" />
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
43 ... </label><br />
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
44 ... <label>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
45 ... <input type="checkbox" name="remember" /> Remember me
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
46 ... </label>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
47 ... </p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
48 ... </form>""")
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
49 >>> filler = HTMLFormFiller(data=dict(username='john', remember=True))
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
50 >>> print(template.generate() | filler)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
51 <form>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
52 <p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
53 <label>User name:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
54 <input type="text" name="username" value="john"/>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
55 </label><br/>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
56 <label>Password:
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
57 <input type="password" name="password"/>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
58 </label><br/>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
59 <label>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
60 <input type="checkbox" name="remember" checked="checked"/> Remember me
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
61 </label>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
62 </p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
63 </form>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
64
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
65 .. note:: This processing is done without in any way reparsing the template
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
66 output. As any stream filter it operates after the template output is
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
67 generated but *before* that output is actually serialized.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
68
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
69 The filter will of course also handle radio buttons as well as ``<select>`` and
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
70 ``<textarea>`` elements. For radio buttons to be marked as checked, the value in
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
71 the data dictionary needs to match the ``value`` attribute of the ``<input>``
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
72 element, or evaluate to a truth value if the element has no such attribute. For
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
73 options in a ``<select>`` box to be marked as selected, the value in the data
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
74 dictionary needs to match the ``value`` attribute of the ``<option>`` element,
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
75 or the text content of the option if it has no ``value`` attribute. Password and
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
76 file input fields are not populated, as most browsers would ignore that anyway
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
77 for security reasons.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
78
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
79 You'll want to make sure that the values in the data dictionary have already
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
80 been converted to strings. While the filter may be able to deal with non-string
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
81 data in some cases (such as check boxes), in most cases it will either not
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
82 attempt any conversion or not produce the desired results.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
83
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
84 You can restrict the form filler to operate only on a specific ``<form>`` by
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
85 passing either the ``id`` or the ``name`` keyword argument to the initializer.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
86 If either of those is specified, the filter will only apply to form tags with
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
87 an attribute matching the specified value.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
88
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
89
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
90 HTML Sanitizer
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
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
93 The filter ``genshi.filters.html.HTMLSanitizer`` filter can be used to clean up
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
94 user-submitted HTML markup, removing potentially dangerous constructs that could
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
95 be used for various kinds of abuse, such as cross-site scripting (XSS) attacks:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
96
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
97 .. code-block:: pycon
500
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 >>> from genshi.filters import HTMLSanitizer
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
100 >>> from genshi.input import HTML
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
101
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
102 >>> html = HTML("""<div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
103 ... <p>Innocent looking text.</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
104 ... <script>alert("Danger: " + document.cookie)</script>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
105 ... </div>""")
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
106 >>> sanitize = HTMLSanitizer()
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
107 >>> print(html | sanitize)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
108 <div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
109 <p>Innocent looking text.</p>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
110 </div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
111
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
112 In this example, the ``<script>`` tag was removed from the output.
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
113
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
114 You can determine which tags and attributes should be allowed by initializing
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
115 the filter with corresponding sets. See the API documentation for more
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
116 information.
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 Inline ``style`` attributes are forbidden by default. If you allow them, the
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
119 filter will still perform sanitization on the contents any encountered inline
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
120 styles: the proprietary ``expression()`` function (supported only by Internet
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
121 Explorer) is removed, and any property using an ``url()`` which a potentially
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
122 dangerous URL scheme (such as ``javascript:``) are also stripped out:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
123
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
124 .. code-block:: pycon
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
125
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
126 >>> from genshi.filters import HTMLSanitizer
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
127 >>> from genshi.input import HTML
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
128
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
129 >>> html = HTML("""<div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
130 ... <br style="background: url(javascript:alert(document.cookie); color: #000" />
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
131 ... </div>""")
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
132 >>> sanitize = HTMLSanitizer(safe_attrs=HTMLSanitizer.SAFE_ATTRS | set(['style']))
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
133 >>> print(html | sanitize)
500
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
134 <div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
135 <br style="color: #000"/>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
136 </div>
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
137
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
138 .. warning:: You should probably not rely on the ``style`` filtering, as
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
139 sanitizing mixed HTML, CSS, and Javascript is very complicated and
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
140 suspect to various browser bugs. If you can somehow get away with
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
141 not allowing inline styles in user-submitted content, that would
0742f421caba Merged revisions 487-603 via svnmerge from
cmlenz
parents:
diff changeset
142 definitely be the safer route to follow.
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
143
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
144
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
145 Transformer
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
146 ===========
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
147
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
148 The filter ``genshi.filters.transform.Transformer`` provides a convenient way to
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
149 transform or otherwise work with markup event streams. It allows you to specify
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
150 which parts of the stream you're interested in with XPath expressions, and then
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
151 attach a variety of transformations to the parts that match:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
152
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
153 .. code-block:: pycon
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
154
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
155 >>> from genshi.builder import tag
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
156 >>> from genshi.core import TEXT
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
157 >>> from genshi.filters import Transformer
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
158 >>> from genshi.input import HTML
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
159
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
160 >>> html = HTML('''<html>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
161 ... <head><title>Some Title</title></head>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
162 ... <body>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
163 ... Some <em>body</em> text.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
164 ... </body>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
165 ... </html>''')
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
166
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
167 >>> print(html | Transformer('body/em').map(unicode.upper, TEXT)
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
168 ... .unwrap().wrap(tag.u).end()
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
169 ... .select('body/u')
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
170 ... .prepend('underlined '))
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
171 <html>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
172 <head><title>Some Title</title></head>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
173 <body>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
174 Some <u>underlined BODY</u> text.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
175 </body>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
176 </html>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
177
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
178 This example sets up a transformation that:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
179
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
180 1. matches any `<em>` element anywhere in the body,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
181 2. uppercases any text nodes in the element,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
182 3. strips off the `<em>` start and close tags,
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
183 4. wraps the content in a `<u>` tag, and
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
184 5. inserts the text `underlined` inside the `<u>` tag.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
185
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
186 A number of commonly useful transformations are available for this filter.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
187 Please consult the API documentation a complete list.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
188
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
189 In addition, you can also perform custom transformations. For example, the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
190 following defines a transformation that changes the name of a tag:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
191
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
192 .. code-block:: pycon
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
193
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
194 >>> from genshi import QName
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
195 >>> from genshi.filters.transform import ENTER, EXIT
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
196
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
197 >>> class RenameTransformation(object):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
198 ... def __init__(self, name):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
199 ... self.name = QName(name)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
200 ... def __call__(self, stream):
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
201 ... for mark, (kind, data, pos) in stream:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
202 ... if mark is ENTER:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
203 ... data = self.name, data[1]
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
204 ... elif mark is EXIT:
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
205 ... data = self.name
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
206 ... yield mark, (kind, data, pos)
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
207
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
208 A transformation can be any callable object that accepts an augmented event
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
209 stream. In this case we define a class, so that we can initialize it with the
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
210 tag name.
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 Custom transformations can be applied using the `apply()` method of a
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
213 transformer instance:
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 >>> xform = Transformer('body//em').map(unicode.upper, TEXT) \
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
218 >>> xform = xform.apply(RenameTransformation('u'))
902
09cc3627654c Sync `experimental/inline` branch with [source:trunk@1126].
cmlenz
parents: 820
diff changeset
219 >>> print(html | xform)
820
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
220 <html>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
221 <head><title>Some Title</title></head>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
222 <body>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
223 Some <u>BODY</u> text.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
224 </body>
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
225 </html>
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 .. note:: The transformation filter was added in Genshi 0.5.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
228
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 Translator
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
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
233 The ``genshi.filters.i18n.Translator`` filter implements basic support for
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
234 internationalizing and localizing templates. When used as a filter, it
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
235 translates a configurable set of text nodes and attribute values using a
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
236 ``gettext``-style translation function.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
237
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
238 The ``Translator`` class also defines the ``extract`` class method, which can
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
239 be used to extract localizable messages from a template.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
240
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
241 Please refer to the API documentation for more information on this filter.
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
242
1837f39efd6f Sync (old) experimental inline branch with trunk@1027.
cmlenz
parents: 500
diff changeset
243 .. note:: The translation filter was added in Genshi 0.4.
Copyright (C) 2012-2017 Edgewall Software