~jonas-drange/ubuntu-start-page/1252899-mobile-friendly

« back to all changes in this revision

Viewing changes to src/Mako-0.1.9/doc/unicode.html

  • Committer: Matthew Nuzum
  • Date: 2008-04-18 01:58:53 UTC
  • Revision ID: matthew.nuzum@canonical.com-20080418015853-2b8rf979z2c2exxl
adding files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<html>
 
2
<head>
 
3
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 
4
        <title>Mako Documentation - The Unicode Chapter</title>
 
5
        
 
6
    <link rel="stylesheet" href="docs.css"></link>
 
7
    <link rel="stylesheet" href="highlight.css"></link>
 
8
    
 
9
 
 
10
 
 
11
 
 
12
 
 
13
</head>
 
14
<body>
 
15
 
 
16
 
 
17
 
 
18
 
 
19
 
 
20
 
 
21
 
 
22
 
 
23
 
 
24
 
 
25
<div id="topanchor"><a name="top">&nbsp;</a></div>
 
26
 
 
27
<div id="pagecontrol"><a href="index.html">Multiple Pages</a> | <a href="documentation.html">One Page</a></div>
 
28
 
 
29
<h1>Mako Documentation</h1>
 
30
 
 
31
<div class="versionheader">Version: 0.1.9   Last Updated: 09/25/07 16:19:18</div>
 
32
 
 
33
 
 
34
 
 
35
 
 
36
 
 
37
 
 
38
 
 
39
<A name=""></a>
 
40
 
 
41
 
 
42
    <div class="topnav">
 
43
 
 
44
    
 
45
    <div class="toolbar">
 
46
        <div class="prevnext">
 
47
            Previous: <a href="filtering.html">Filtering and Buffering</a>
 
48
 
 
49
            |
 
50
            Next: <a href="caching.html">Caching</a>
 
51
        </div>
 
52
        <h3><a href="index.html">Table of Contents</a></h3>
 
53
    </div>
 
54
 
 
55
 
 
56
    <br/>
 
57
        <a href="#unicode">The Unicode Chapter</a>
 
58
        
 
59
        
 
60
    <ul>
 
61
        <li><A style="" href="unicode.html#unicode_specifying">Specifying the Encoding of a Template File</a></li>
 
62
        
 
63
            
 
64
    <ul>
 
65
    </ul>
 
66
 
 
67
        <li><A style="" href="unicode.html#unicode_handling">Handling Expressions</a></li>
 
68
        
 
69
            
 
70
    <ul>
 
71
    </ul>
 
72
 
 
73
        <li><A style="" href="unicode.html#unicode_defining">Defining Output Encoding</a></li>
 
74
        
 
75
            
 
76
    <ul>
 
77
        <li><A style="" href="unicode.html#unicode_defining_buffer">Buffer Selection</a></li>
 
78
        
 
79
            
 
80
    <ul>
 
81
    </ul>
 
82
 
 
83
    </ul>
 
84
 
 
85
    </ul>
 
86
 
 
87
        </div>
 
88
 
 
89
 
 
90
 
 
91
 
 
92
 
 
93
 
 
94
 
 
95
 
 
96
 
 
97
 
 
98
 
 
99
    
 
100
    <A name="unicode"></a>
 
101
    
 
102
    <div class="section">
 
103
    
 
104
 
 
105
    <h3>The Unicode Chapter</h3>
 
106
    
 
107
    
 
108
 
 
109
<p>The Python language in the 2.x series supports two ways of representing string objects.  One is the <code>string</code> type and the other is the <code>unicode</code> type, both of which extend a type called <code>basestring</code>.  A key issue in Python, which is hopefully to be resolved in Python 3000, is that objects of type <code>string</code> (i.e. created from an expression such as <code>&quot;hello world&quot;</code>) contain no information regarding what <strong>encoding</strong> the data is stored in.   For this reason they are often referred to as <strong>byte strings</strong>.  The origins of this come from Python's background of being developed before the Unicode standard was even available, back when strings were C-style strings and were just that, a series of bytes.  Strings that had only values below 128 just happened to be <strong>ascii</strong> strings and were printable on the console, whereas strings with values above 128 would produce all kinds of graphical characters and bells.
 
110
</p>
 
111
<p>Contrast the Python <code>string</code> type with the Python <code>unicode</code> type.  Objects of this type are created whenever you say something like <code>u&quot;hello world&quot;</code>.  In this case, Python represents each character in the string internally using multiple bytes per character (something similar to UTF-16).  Whats important is that when using the <code>unicode</code> type to store strings, Python knows the data's encoding; its in its own internal format.  Whereas when using the <code>string</code> type, it does not.
 
112
</p>
 
113
<p>When Python attempts to treat a byte-string as a string, which means its attempting to compare/parse its characters, to coerce it into another encoding, or to decode it to a unicode object, it has to guess what the encoding is.  In this case, it will pretty much always guess the encoding as <code>ascii</code>...and if the bytestring contains bytes above value 128, you'll get an error.
 
114
</p>
 
115
<p>There is one operation that Python <em>can</em> do with a non-ascii bytestring, and its a great source of confusion:  it can dump the bytestring straight out to a stream or a file, with nary a care what the encoding is.  To Python, this is pretty much like dumping any other kind of binary data (like an image) to a stream somewhere.  So in a lot of cases, programs that embed all kinds of international characters and encodings into plain byte-strings (i.e. using <code>&quot;hello world&quot;</code> style literals) can fly right through their run, sending reams of strings out to whereever they are going, and the programmer, seeing the same output as was expressed in the input, is now under the illusion that his or her program is Unicode-compliant.  In fact, their program has no unicode awareness whatsoever, and similarly has no ability to interact with libraries that <em>are</em> unicode aware.
 
116
</p>
 
117
<p>Particularly, some template languages like Cheetah, as well as earlier versions of Myghty, will treat expressions in this manner..they just go right through.  Theres nothing "incorrect" about this, but Mako, since it deals with unicode internally, usually requires explicitness when dealing with non-ascii encodings.  Additionally, if you ever need to handle unicode strings and other kinds of encoding conversions more intelligently, the usage of raw bytestrings quickly becomes a nightmare, since you are sending the Python interpreter collections of bytes for which it can make no intelligent decisions with regards to encoding.
 
118
</p>
 
119
<p>In Mako, all parsed template constructs and output streams are handled internally as Python <code>unicode</code> objects.  Its only at the point of <code>render()</code> that this unicode stream is rendered into whatever the desired output encoding is.  The implication here is that the template developer must ensure that the encoding of all non-ascii templates is explicit, that all non-ascii-encoded expressions are in one way or another converted to unicode, and that the output stream of the template is handled as a unicode stream being encoded to some encoding.
 
120
</p>
 
121
 
 
122
 
 
123
    
 
124
    <A name="unicode_specifying"></a>
 
125
    
 
126
    <div class="subsection">
 
127
    
 
128
 
 
129
    <h3>Specifying the Encoding of a Template File</h3>
 
130
    
 
131
    
 
132
 
 
133
<p>This is the most basic encoding-related setting, and it is equivalent to Python's "magic encoding comment", as described in <a href='http://www.python.org/dev/peps/pep-0263/'>pep-0263</a>.  Any template that contains non-ascii characters  requires that this comment be present so that Mako can decode to unicode (and also make usage of Python's AST parsing services).  Mako's lexer will use this encoding in order to convert the template source into a <code>unicode</code> object before continuing its parsing:
 
134
</p>
 
135
 
 
136
    
 
137
    
 
138
 
 
139
    <div class="code">
 
140
        <div class="highlight" ><pre><span class="cp">## -*- coding: utf-8 -*-</span>
 
141
 
 
142
Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
 
143
</pre></div>
 
144
 
 
145
    </div>
 
146
<p>For the picky, the regular expression used is derived from that of the abovementioned pep:
 
147
</p>
 
148
 
 
149
    
 
150
    
 
151
 
 
152
    <div class="code">
 
153
        <div class="highlight" ><pre><span class="c">#.*coding[:=]\s*([-\w.]+).*\n</span>
 
154
</pre></div>
 
155
 
 
156
    </div>
 
157
<p>The lexer will convert to unicode in all cases, so that if any characters exist in the template that are outside of the specified encoding (or the default of <code>ascii</code>), the error will be immediate.
 
158
</p>
 
159
<p>As an alternative, the template encoding can be specified programmatically to either <code>Template</code> or <code>TemplateLookup</code> via the <code>input_encoding</code> parameter:
 
160
</p>
 
161
 
 
162
    
 
163
    
 
164
 
 
165
    <div class="code">
 
166
        <div class="highlight" ><pre><span class="n">t</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;./&#39;</span><span class="p">],</span> <span class="n">input_encoding</span><span class="o">=</span><span class="s">&#39;utf-8&#39;</span><span class="p">)</span>
 
167
</pre></div>
 
168
 
 
169
    </div>
 
170
<p>The above will assume all located templates specify <code>utf-8</code> encoding, unless the template itself contains its own magic encoding comment, which takes precedence.
 
171
</p>
 
172
 
 
173
 
 
174
 
 
175
            <a href="#top">back to section top</a>
 
176
    </div>
 
177
 
 
178
 
 
179
 
 
180
    
 
181
    <A name="unicode_handling"></a>
 
182
    
 
183
    <div class="subsection">
 
184
    
 
185
 
 
186
    <h3>Handling Expressions</h3>
 
187
    
 
188
    
 
189
 
 
190
<p>The next area that encoding comes into play is in expression constructs.  By default, Mako's treatment of an expression like this:
 
191
</p>
 
192
 
 
193
    
 
194
    
 
195
 
 
196
    <div class="code">
 
197
        <div class="highlight" ><pre><span class="cp">${</span><span class="s">&quot;hello world&quot;</span><span class="cp">}</span>
 
198
</pre></div>
 
199
 
 
200
    </div>
 
201
<p>looks something like this:
 
202
</p>
 
203
 
 
204
    
 
205
    
 
206
 
 
207
    <div class="code">
 
208
        <div class="highlight" ><pre><span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">unicode</span><span class="p">(</span><span class="s">&quot;hello world&quot;</span><span class="p">))</span>
 
209
</pre></div>
 
210
 
 
211
    </div>
 
212
<p>That is, <em></em>the output of all expressions is run through the <code>unicode</code> builtin<em></em>.  This is the default setting, and can be modified to expect various encodings.  The <code>unicode</code> step serves both the purpose of rendering non-string expressions into strings (such as integers or objects which contain <code>__str()__</code> methods), and to ensure that the final output stream is constructed as a unicode object.  The main implication of this is that <strong>any raw bytestrings that contain an encoding other than ascii must first be decoded to a Python unicode object</strong>.   It means you can't say this:
 
213
</p>
 
214
 
 
215
    
 
216
    
 
217
 
 
218
    <div class="code">
 
219
        <div class="highlight" ><pre><span class="cp">${</span><span class="s">&quot;voix m’a réveillé.&quot;</span><span class="cp">}</span>  <span class="cp">## error !</span>
 
220
</pre></div>
 
221
 
 
222
    </div>
 
223
<p>You must instead say this:
 
224
</p>
 
225
 
 
226
    
 
227
    
 
228
 
 
229
    <div class="code">
 
230
        <div class="highlight" ><pre><span class="cp">${</span><span class="n">u</span><span class="s">&quot;voix m’a réveillé.&quot;</span><span class="cp">}</span>  <span class="cp">## OK !</span>
 
231
</pre></div>
 
232
 
 
233
    </div>
 
234
<p>Similarly, if you are reading data from a file, or returning data from some object that is returning a Python bytestring containing a non-ascii encoding, you have to explcitly decode to unicode first, such as:
 
235
</p>
 
236
 
 
237
    
 
238
    
 
239
 
 
240
    <div class="code">
 
241
        <div class="highlight" ><pre><span class="cp">${</span><span class="n">call_my_object</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&#39;utf-8&#39;</span><span class="p">)</span><span class="cp">}</span>
 
242
</pre></div>
 
243
 
 
244
    </div>
 
245
<p>If you want a certain encoding applied to <em>all</em> expressions, override the <code>unicode</code> builtin with the <code>decode</code> builtin at the <code>Template</code> or <code>TemplateLookup</code> level:
 
246
</p>
 
247
 
 
248
    
 
249
    
 
250
 
 
251
    <div class="code">
 
252
        <div class="highlight" ><pre><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">templatetext</span><span class="p">,</span> <span class="n">default_filters</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;decode.utf8&#39;</span><span class="p">])</span>
 
253
</pre></div>
 
254
 
 
255
    </div>
 
256
<p>Note that the built-in <code>decode</code> object is slower than the <code>unicode</code> function, since unlike <code>unicode</code> its not a Python builtin, and it also checks the type of the incoming data to determine if string conversion is needed first.
 
257
</p>
 
258
<p>The <code>default_filters</code> argument can be used to entirely customize the filtering process of expressions.  This argument is described in <a href="filtering.html#filtering_expression_defaultfilters">The default_filters Argument</a>.
 
259
</p>
 
260
 
 
261
 
 
262
 
 
263
            <a href="#top">back to section top</a>
 
264
    </div>
 
265
 
 
266
 
 
267
 
 
268
    
 
269
    <A name="unicode_defining"></a>
 
270
    
 
271
    <div class="subsection">
 
272
    
 
273
 
 
274
    <h3>Defining Output Encoding</h3>
 
275
    
 
276
    
 
277
 
 
278
<p>Now that we have a template which produces a pure unicode output stream, all the hard work is done.  We can take the output and do anything with it.
 
279
</p>
 
280
<p>As stated in the "Usage" chapter, both <code>Template</code> and <code>TemplateLookup</code> accept <code>output_encoding</code> and <code>encoding_errors</code> parameters which can be used to encode the output in any Python supported codec:
 
281
</p>
 
282
 
 
283
    
 
284
    
 
285
 
 
286
    <div class="code">
 
287
        <div class="highlight" ><pre><span class="k">from</span> <span class="nn">mako.template</span> <span class="k">import</span> <span class="n">Template</span>
 
288
<span class="k">from</span> <span class="nn">mako.lookup</span> <span class="k">import</span> <span class="n">TemplateLookup</span>
 
289
 
 
290
<span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;/docs&#39;</span><span class="p">],</span> <span class="n">output_encoding</span><span class="o">=</span><span class="s">&#39;utf-8&#39;</span><span class="p">,</span> <span class="n">encoding_errors</span><span class="o">=</span><span class="s">&#39;replace&#39;</span><span class="p">)</span>
 
291
 
 
292
<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">mylookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">&quot;foo.txt&quot;</span><span class="p">)</span>
 
293
<span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
 
294
</pre></div>
 
295
 
 
296
    </div>
 
297
<p>And <code>render_unicode()</code> will return the template output as a Python <code>unicode</code> object:
 
298
</p>
 
299
 
 
300
    
 
301
    
 
302
 
 
303
    <div class="code">
 
304
        <div class="highlight" ><pre><span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span>
 
305
</pre></div>
 
306
 
 
307
    </div>
 
308
<p>The above method disgards the output encoding keyword argument; you can encode yourself by saying:
 
309
</p>
 
310
 
 
311
    
 
312
    
 
313
 
 
314
    <div class="code">
 
315
        <div class="highlight" ><pre><span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf-8&#39;</span><span class="p">,</span> <span class="s">&#39;replace&#39;</span><span class="p">)</span>
 
316
</pre></div>
 
317
 
 
318
    </div>
 
319
 
 
320
 
 
321
    
 
322
    <A name="unicode_defining_buffer"></a>
 
323
    
 
324
    <div class="subsection">
 
325
    
 
326
 
 
327
    <h3>Buffer Selection</h3>
 
328
    
 
329
    
 
330
 
 
331
<p>Mako does play some games with the style of buffering used internally, to maximize performance.  Since the buffer is by far the most heavily used object in a render operation, its important!
 
332
</p>
 
333
<p>When calling <code>render()</code> on a template that does not specify any output encoding (i.e. its <code>ascii</code>), Python's <code>cStringIO</code> module, which cannot handle encoding of non-ascii <code>unicode</code> objects (even though it can send raw bytestrings through), is used for buffering.  Otherwise, a custom Mako class called <code>FastEncodingBuffer</code> is used, which essentially is a super dumbed-down version of <code>StringIO</code> that gathers all strings into a list and uses <code>u''.join(elements)</code> to produce the final output - its markedly faster than <code>StringIO</code>.
 
334
</p>
 
335
 
 
336
 
 
337
 
 
338
 
 
339
    </div>
 
340
 
 
341
 
 
342
 
 
343
 
 
344
    </div>
 
345
 
 
346
 
 
347
 
 
348
 
 
349
            <a href="#top">back to section top</a>
 
350
    </div>
 
351
 
 
352
 
 
353
</html>
 
354
 
 
355
 
 
356
    <div class="toolbar">
 
357
        <div class="prevnext">
 
358
            Previous: <a href="filtering.html">Filtering and Buffering</a>
 
359
 
 
360
            |
 
361
            Next: <a href="caching.html">Caching</a>
 
362
        </div>
 
363
        <h3><a href="index.html">Table of Contents</a></h3>
 
364
    </div>
 
365
 
 
366
 
 
367
 
 
368
 
 
369
 
 
370
 
 
371
</body>
 
372
</html>
 
373
 
 
374
 
 
375
 
 
376
 
 
377