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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
.. _caveats:
Template Caveats
################
================
[% %] and [%+ %]
================
``[% %]`` is used by Template Toolkit to enclose some TT code, which will be
often be replaced by a variable or something else when the template is
rendered.
Generally, you should follow the exact text layout of the English version, but
if you need to change the position of a ``[% %]`` block in a line, you should
be aware of this rule: when two ``[% %]`` blocks are following each other,
the second member will not be separated with a space from the first one, even
if you separate them with a space. For instance, these lines of template code:
.. raw:: html
<pre>
[% ELSIF message_tag == "bug_duplicate_of" %]
This [% terms.bug %] has been marked as a duplicate of <mark>[% terms.bug %] [% dupe_of FILTER html %]</mark>
</pre>
will display in the browser as:
.. code-block:: text
This bug has been marked as duplicate of bug12345
To preserve whitespace, you should add a "+" sign inside the second member:
.. raw:: html
<pre>
[% ELSIF message_tag == "bug_duplicate_of" %]
This [% terms.bug %] has been marked as a duplicate of [% terms.bug %] [%<mark>+</mark> dupe_of FILTER html %]
</pre>
Will then be displayed as:
.. code-block:: text
This bug has been marked as duplicate of bug 12345
This is the same when a [% %] member is at the beginning of a new line. These
lines of template code:
.. code-block:: text
[% IF groups_added_to.size %]
<li>
The account has been added to the
[% groups_added_to.join(', ') FILTER html %]
group[% 's' IF groups_added_to.size > 1 %].
</li>
[% END %]
will be shown as:
.. code-block:: text
The account has been added to thebz_sudo_protect group.
Again, insert a "+" sign:
.. raw:: html
<pre>
[% IF groups_added_to.size %]
<li>
The account has been added to the
[%<mark>+</mark> groups_added_to.join(', ') FILTER html %]
group[% 's' IF groups_added_to.size > 1 %].
</li>
[% END %]
</pre>
So that the sentence is displayed as:
.. code-block:: text
The account has been added to the bz_sudo_protect group.
Sometimes, pluralization is dealt with using explicit Template Toolkit code,
which needs to be altered for your language.
For example, if one wanted to localize the previous example into French,
the words order would not be not correct and the markup has to be rearranged.
The member ``[% groups_added_to.join(', ') FILTER html %]`` will actually display
the name of one group or several group names separated with a comma and a space (', ').
The member ``[% 's' IF groups_added_to.size > 1 %]`` will add an "s"
to the word "group" if there is more than one. In French, the group name should be put
after the term "group" and words need to be declensed when plural is used. That
would give for instance the following:
.. code-block:: text
[% IF groups_added_to.size %]
<li>
Le compte a été ajouté
[% IF groups_added_to.size > 1 %]
aux groupes[% ELSE %]au groupe[% END %][%+ groups_added_to.join(', ') FILTER html %].
</li>
[% END %]
The browser would then display for one group:
.. raw:: html
Le compte a été ajouté <mark>au groupe</mark> bz_sudo_protect
And for several groups:
.. raw:: html
Le compte a été ajouté <mark>aux groupes</mark> bz_sudo_protect, canconfirm, editbugs
===============================
Double quotes and single quotes
===============================
Template Toolkit strings in directives are quote-delimited, and can use either
single or double quotes. But, obviously, you can't put double quotes inside
a double-quoted string. The following example will break the user interface:
.. code-block:: text
[% ELSIF message_tag == "buglist_adding_field" %]
[% title = "Adding field to search page..." %]
[% link = "Click here if the page "does not" redisplay automatically." %]
Instead, you can escape them with a backslash ("\"):
.. code-block:: text
[% ELSIF message_tag == "buglist_adding_field" %]
[% title = "Adding field to search page..." %]
[% link = "Click here if the page \"does not\" redisplay automatically." %]
Or you can substitute the surrounding double quotes with single quotes:
.. code-block:: text
[% ELSIF message_tag == "buglist_adding_field" %]
[% title = "Adding field to search page..." %]
[% link = 'Click here if the page "does not" redisplay automatically.' %]
===========
Declensions
===========
English only deals with one plural form and has no declension. Your locale
might need to implement declensions, and reorder words inside a sentence.
Let's say we have the following:
.. code-block:: text
[% IF !Param("allowbugdeletion") %]
<p>
Sorry, there
[% IF comp.bug_count > 1 %]
are [% comp.bug_count %] [%+ terms.bugs %]
[% ELSE %]
is [% comp.bug_count %] [%+ terms.bug %]
[% END %]
pending for this component. You should reassign
[% IF comp.bug_count > 1 %]
these [% terms.bugs %]
[% ELSE %]
this [% terms.bug %]
[% END %]
to another component before deleting this component.
</p>
[% ELSE %]
Here, the following expression comp.bug_count obviously gives the count number of bugs
for a component. ``IF comp.bug_count > 1`` means "if there are more than one bug".
Let's say your language has to deal with three plural forms and that the terms "bug" and
"pending" should be declensed as well.
First, you'll have to populate the :file:`/template/en/default/global/variables.none.tmpl`
file with the declensions for "bug", which would give something like:
.. code-block:: text
[% terms = {
"bug0" => "declension for zero bug",
"bug" => "declension for one bug",
"bug2" => "declension for two bugs",
"bug3" => "declension for three bugs",
"bugs" => "declension for more than three bugs",
Then, the previous code should look like:
.. code-block:: text
[% IF !Param("allowbugdeletion") %]
<p>
Sorry, there
[% IF comp.bug_count > 3 %]
are [% comp.bug_count %] pending [% terms.bugs %]
[% ELSE %]
[% IF comp.bug_count == 0 %]
is [% comp.bug_count %] pending [% terms.bug0 %]
[% ELSE %]
[% IF comp.bug_count == 1 %]
is [% comp.bug_count %] pending [% terms.bug %]
[% ELSE %]
[% IF comp.bug_count == 2 %]
are [% comp.bug_count %] pending [% terms.bug2 %]
[% ELSE %]
[% IF comp.bug_count == 3 %]
are [% comp.bug_count %] pending [% terms.bug3 %]
[% END %]
for this component. You should reassign
[% IF comp.bug_count > 1 %]
these [% terms.bugs %]
[% ELSE %]
this [% terms.bug %]
[% END %]
to another component before deleting this component.
</p>
[% ELSE %]
==========
$terms.foo
==========
As seen previously, term substitutions can be made across all template files.
Such substitutions are defined in ``*.none.tmpl`` files, which are:
* template/en/default/global/field-descs.none.tmpl
* template/en/default/global/variables.none.tmpl
* template/en/default/global/value-descs.none.tmpl
* template/en/default/global/reason-descs.none.tmpl
* template/en/default/global/setting-descs.none.tmpl
* template/en/default/bug/field-help.none.tmpl
These variables appear in the template files under three different forms.
``[% terms.foo %]`` is the standard, simple substitution of a term into a run
of text. ``$terms.foo`` is used when substituting into a Template Toolkit
string, and ``${terms.foo}`` is used when you need to separate the variable
name from the surrounding content to resolve ambiguity.
To illustrate this last point: during your localizing contribution, you may
have to reorganize sentences, and sometimes a variable of the form
``$terms.foo`` will come at the end of a sentence which ends with a full stop,
like this:
.. raw:: html
<pre>
defaultplatform => "Plateforme qui est pré-sélectionnée dans le formulaire de soumission " _
"de <mark>$terms.bug.</mark><br> " _
"Vous pouvez laisser ce champ vide : " _
"Bugzilla utilisera alors la plateforme indiquée par le navigateur.",
</pre>
If you leave it like that, the substitution would not take place and the
result in the user interface would be wrong. Instead, change the form
``$terms.foo`` into the form ``${terms.foo}``, like this:
.. raw:: html
<pre>
defaultplatform => "Plateforme qui est pré-sélectionnée dans le formulaire de soumission " _
"de <mark>${terms.bug}.</mark><br> " _
"Vous pouvez laisser ce champ vide : " _
"Bugzilla utilisera alors la plateforme indiquée par le navigateur.",
</pre>
========
b[% %]ug
========
Once and a while you would find something like:
.. code-block:: text
A b[% %]ug on b[% %]ugs.debian.org.
You remember that the file :file:`variables.none.tmpl` holds the substitutions
for different terms. The release process of Bugzilla has a script that
parses all the templates to check if you wrote the bare word "bug" instead of
"$terms.bug" or similar, to make sure that this feature keeps working.
In the example above, we really want to write the term "bug" and we neither
want it to be substituted afterwards nor be warned by the test script.
This check only looks at the English terms bug, bugs, and Bugzilla, so you can
safely ignore the ``[% %]`` and localize ``b[% %]ug``, but you would keep
``b[% %]ugs.debian.org`` unchanged as it's a URL.
|