File: i18n.html

package info (click to toggle)
jinja 1.2-2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 1,408 kB
  • ctags: 1,171
  • sloc: python: 6,438; ansic: 397; makefile: 74
file content (192 lines) | stat: -rw-r--r-- 13,484 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <title>Internationalization &mdash; Jinja Documentation</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <link rel="stylesheet" href="style.css" type="text/css">
  <style type="text/css">
    .syntax  { background: #ffffff; }
.syntax .c { color: #888888 } /* Comment */
.syntax .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.syntax .k { color: #008800; font-weight: bold } /* Keyword */
.syntax .cm { color: #888888 } /* Comment.Multiline */
.syntax .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.syntax .c1 { color: #888888 } /* Comment.Single */
.syntax .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.syntax .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.syntax .ge { font-style: italic } /* Generic.Emph */
.syntax .gr { color: #aa0000 } /* Generic.Error */
.syntax .gh { color: #303030 } /* Generic.Heading */
.syntax .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.syntax .go { color: #888888 } /* Generic.Output */
.syntax .gp { color: #555555 } /* Generic.Prompt */
.syntax .gs { font-weight: bold } /* Generic.Strong */
.syntax .gu { color: #606060 } /* Generic.Subheading */
.syntax .gt { color: #aa0000 } /* Generic.Traceback */
.syntax .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.syntax .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.syntax .kp { color: #008800 } /* Keyword.Pseudo */
.syntax .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.syntax .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.syntax .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.syntax .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.syntax .na { color: #336699 } /* Name.Attribute */
.syntax .nb { color: #003388 } /* Name.Builtin */
.syntax .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.syntax .no { color: #003366; font-weight: bold } /* Name.Constant */
.syntax .nd { color: #555555 } /* Name.Decorator */
.syntax .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.syntax .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.syntax .nl { color: #336699; font-style: italic } /* Name.Label */
.syntax .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.syntax .py { color: #336699; font-weight: bold } /* Name.Property */
.syntax .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.syntax .nv { color: #336699 } /* Name.Variable */
.syntax .ow { color: #008800 } /* Operator.Word */
.syntax .w { color: #bbbbbb } /* Text.Whitespace */
.syntax .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.syntax .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.syntax .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.syntax .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.syntax .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.syntax .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.syntax .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.syntax .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.syntax .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.syntax .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.syntax .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.syntax .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.syntax .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.syntax .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.syntax .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.syntax .bp { color: #003388 } /* Name.Builtin.Pseudo */
.syntax .vc { color: #336699 } /* Name.Variable.Class */
.syntax .vg { color: #dd7700 } /* Name.Variable.Global */
.syntax .vi { color: #3333bb } /* Name.Variable.Instance */
.syntax .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
  </style>
</head>
<body>
  <div id="content">
    
      <h1 class="heading"><span>Jinja</span></h1>
      <h2 class="subheading">Internationalization</h2>
    
    
    <div id="toc">
      <h2>Navigation</h2>
      <ul>
        <li><a href="index.html">back to index</a></li>
      </ul>
      
        <h2>Contents</h2>
        <ul class="contents">
        
          <li><a href="#writing-a-translator">Writing A Translator</a></li>
        
          <li><a href="#translator-factory">Translator Factory</a></li>
        
          <li><a href="#collecting-translations">Collecting Translations</a></li>
        
        </ul>
      
    </div>
    
    <div id="contentwrapper">
      <p>Jinja includes support for internationalized templates. Because usually the
application includes i18n/l10n code too there is no script to collect
translatable strings and no default translation interface. A simple
implementation wouldn't fit into every application so there are a few things
you have to do.</p>
<div class="section">
<h2><a id="writing-a-translator" name="writing-a-translator">Writing A Translator</a></h2>
<p>The most important thing is writing a translator and subclassing the
Environment so that Jinja knows about the translator. Then you have to
think of how to resolve the current language. You probably use Jinja in a
multithreaded environment where each thread (request) might want to have
a different language. The best way is putting the current language into
the context, this can work automatically if you create a helper function
for template rendering. But that's up to you.</p>
<p>However. For many web applications this might be a way:</p>
<div class="syntax"><pre><span class="k">from</span> <span class="nn">jinja</span> <span class="k">import</span> <span class="n">Environment</span>
<span class="k">from</span> <span class="nn">myapplication</span> <span class="k">import</span> <span class="n">get_translator</span>

<span class="k">class</span> <span class="nc">ApplicationTranslator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">language</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">language</span> <span class="o">=</span> <span class="n">language</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">translator</span> <span class="o">=</span> <span class="n">get_translator</span><span class="p">(</span><span class="n">language</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">gettext</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">string</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">translator</span><span class="o">.</span><span class="n">ugettext</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">ngettext</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">singular</span><span class="p">,</span> <span class="n">plural</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">translator</span><span class="o">.</span><span class="n">ungettext</span><span class="p">(</span><span class="n">singuarl</span><span class="p">,</span> <span class="n">plural</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">ApplicationEnvironment</span><span class="p">(</span><span class="n">Environment</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">get_translator</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">ApplicationTranslator</span><span class="p">(</span><span class="n">context</span><span class="p">[</span><span class="s">&#39;LANGUAGE&#39;</span><span class="p">])</span>


<span class="n">env</span> <span class="o">=</span> <span class="n">ApplicationEnvironment</span><span class="p">()</span>
<span class="n">tmpl</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">&#39;index.html&#39;</span><span class="p">)</span>
<span class="n">tmpl</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">LANGUAGE</span><span class="o">=</span><span class="s">&#39;de_DE&#39;</span><span class="p">)</span>
</pre></div>
<p>This example assumes that you use gettext and have a gettext <cite>Translations</cite>
object which is returned by the <cite>get_translator</cite> function. But you don't
have to use gettext. The only thing Jinja requires is an object with to
functions/methods on it that return and accept unicode strings:
<tt class="docutils literal"><span class="pre">gettext(string)</span></tt> that takes a string, translates and returns it, a
<tt class="docutils literal"><span class="pre">ngettext(singular,</span> <span class="pre">plural,</span> <span class="pre">count)</span></tt> function that returns the correct plural
form for <cite>count</cite> items. Because some languages have no or multiple plural
forms this is necessary.</p>
</div>
<div class="section">
<h2><a id="translator-factory" name="translator-factory">Translator Factory</a></h2>
<p>With Jinja 1.2 onwards it's possible to use a translator factory
instead of an enviornment subclass to create a translator for a context.
A translator factory is passed a context and has to return a translator.
Because of the way classes work you can also assign a translator class
that takes a context object as only argument as factory.</p>
<p>Example:</p>
<div class="syntax"><pre><span class="k">from</span> <span class="nn">jinja</span> <span class="k">import</span> <span class="n">Environment</span>
<span class="k">from</span> <span class="nn">myapplication</span> <span class="k">import</span> <span class="n">get_translator</span>

<span class="k">def</span> <span class="nf">translator_factory</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">get_translator</span><span class="p">(</span><span class="n">context</span><span class="p">[</span><span class="s">&#39;LANGUAGE&#39;</span><span class="p">])</span>

<span class="n">env</span> <span class="o">=</span> <span class="n">ApplicationEnvironment</span><span class="p">(</span><span class="n">translator_factory</span><span class="o">=</span><span class="n">translator_factory</span><span class="p">)</span>
<span class="n">tmpl</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">&#39;index.html&#39;</span><span class="p">)</span>
<span class="n">tmpl</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">LANGUAGE</span><span class="o">=</span><span class="s">&#39;de_DE&#39;</span><span class="p">)</span>
</pre></div>
<p>This example assumes that the translator returned by <cite>get_translator</cite>
already has a gettext and ngettext function that returns unicode strings.</p>
</div>
<div class="section">
<h2><a id="collecting-translations" name="collecting-translations">Collecting Translations</a></h2>
<p>The next step is to collect the translations. Every Jinja environment
provides a function called <cite>get_translations</cite> which collects all
translatable strings from an template.</p>
<p>Example:</p>
<div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">env</span><span class="o">.</span><span class="n">get_translations</span><span class="p">(</span><span class="s">&#39;index.html&#39;</span><span class="p">)</span>
<span class="go">[(1, u&#39;foo&#39;, None), (2, u&#39;Foo&#39;, None), (3, u&#39;%(count)s Foo&#39;, u&#39;%(count)s Foos&#39;)]</span>
</pre></div>
<p>The first item in the tuple is the linenumer, the second one is the
singular form and the third is the plural form if given.</p>
<p>Because Jinja is not bound to gettext you can now use these strings to
create translation files for any translation system.</p>
<p><em>New in Jinja 1.1</em> You can now extract translations from strings according
to the current envrionment settings too by using the environment method
<cite>get_translations_for_string</cite> which takes a string containing a template
as only argument. The return value is the same as for <cite>get_translations</cite>.</p>
</div>

    </div>
  </div>
</body>
<!-- generated on: 2007-11-17 18:18:05.709882
     file id: i18n -->
</html>