File: Gettext.pod

package info (click to toggle)
libtemplate-plugin-gettext-perl 1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 352 kB
  • sloc: perl: 1,317; makefile: 2
file content (373 lines) | stat: -rw-r--r-- 12,502 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
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
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
=for Pod::Coverage ngettextp new

=head1 NAME

Template::Plugin::Gettext - Gettext Support For the Template Toolkit Version 2

=head1 SYNOPSIS

Load the plug-in in templates:

    [% USE Gettext('com.textdomain.my', 'fr', 'utf-8', 'DIRECTORIES'...) %]
    [% Gettext.gettext('Hello, world!') %]

    [% 'Hello, world!' | gettext %]

Or alias "Gettext":

    [% USE gtx = Gettext('com.textdomain.my', 'fr', 'utf-8', 'DIRECTORIES'...) %]
    [% gtx.gettext('Hello, world!') %]

Use method invocations:

    [% Gettext.gettext("Hello, world!") %]
    [% Gettext.xgettext("Hello, {name}!", name => 'John Doe') %]

Or filters (without the prefix):

    [% FILTER gettext %]
    Hello, world!
    [% END %]

    [% 'Hello, world!' | gettext %]

    [% FILTER xgettext(name => 'John Doe') %]
    Hello, {name}!
    [% END %]

You have a multitude of methods available:

    [% gtx.gettext("Hello, user!") %]
    [% gtx.xgettext("Hello, {user}!", user => 'John Doe') %]
    [% gtx.ngettext("One document deleted.",
                    "Multiple documents deleted."),
                    42) %]
    [% gtx.nxgettext("One document deleted.",
                     "{num} documents deleted."),
                     42,
                     num => 42) %]
    [% gtx.npgettext("context..."
                     "One document deleted.",
                     "Multiple documents deleted."),
                     42) %]
    [% gtx.npxgettext("context...",
                      "One document deleted.",
                      "{num} documents deleted."),
                      42,
                      num => 42) %]

=head1 DESCRIPTION

The B<Template::Plugin::Gettext> plug-in makes the
L<GNU gettext API|https://www.gnu.org/software/gettext/> available for
documents using the
L<Template Toolkit version 2|http://template-toolkit.org/>.  See
L<https://github.com/gflohr/Template-Plugin-Gettext> for an overall
picture and the recommended tool-chain.

=head1 FUNCTIONS

The following methods produce translatable content:

=over 4

=item B<[% gtx.gettext(STRING) %]>

Retrieves the translation for B<STRING>.

=item B<[% gtx.xgettext(STRING, PLACEHOLDER1 =E<gt> VALUE1, PLACEHOLDER2 =E<gt> VALUE2, ...) %]>

Gets the translation for a string with placeholders and interpolates values
into it.  Placeholders have the format <{PLACEHOLDER}>.  For a literal
left curly brace you can use this hack:

    [% gtx.xgettext("String with {LBRACE}PLACEHOLDERS{RBRACE}",
                    LBRACE => "{", RBRACE => "}") %]

=item B<[% gtx.pgettext(CONTEXT, STRING) %]>

Retrieves the translation for B<STRING> in context B<CONTEXT>.  You
should use message context to disambiguate identical strings that
require different translations depending on the context.  See this
example for an explanation:

    [% gtx.gettext("State: ") %]
        [% gtx.gettext("Open")] | [% gtx.gettext("Close") %]
    
    [% gtx.gettext("Menu:") %]
        [% gtx.pgettext("menu", "Open")]
        [% gtx.gettext("Save")]
        [% gtx.gettext("Save As")]
        [% gtx.pgettext("menu", "Close")]

The strings "Open" and "Close" in line 2 are adjectives. As 
 menu entries they are verb forms and will have a different
 translation in many languages.

 In doubt: Only use contexts if one of your translators complains
 about a message having multiple meanings.

=item B<[% gtx.pxgettext(CONTEXT, STRING,
                        PLACEHOLDER1 =E<gt> VALUE1,
                        PLACEHOLDER2 =E<gt> VALUE2) %]>

Get the translation for B<STRING> with placeholders in context
B<CONTEXT>.  This is a mixture of C<xgettext()> and C<pgettext()>
above.

=item B<[% gtx.nxgettext(SINGULAR, PLURAL, COUNT,
                         PLACEHOLDER1 =E<gt> VALUE1,
                         PLACEHOLDER2 =E<gt> VALUE2) %]>

Retrieves the translation for the string with the singular form
B<SINGULAR> and the plural from B<PLURAL>, both possibly
containing placeholders.  The correct form is picked based
upon the third argument B<COUNT>.

Example:

    [% gtx.nxgettext("One document deleted",
                     "{num} documents deleted"),
                     count,
                     num => count) %]

In English this will produce "42 documents deleted" if the variable
count has the value 42.  It will produce "One document deleted" if
the variable count has the value 1.

In other languages, the rules for plural forms may be a lot
simpler (for example Chinese, which has no plural) or a lot more 
complicated (for example Russian with two or Slovenian with even
3 plural forms).  Using ngettext() gives your translators the
chance to provide syntactically correct translations for these
cases.

=item B<[% gtx.npxgettext(CONTEXT, SINGULAR, PLURAL, COUNT,
                          PLACEHOLDER1 =E<gt> VALUE1,
                          PLACEHOLDER2 =E<gt> VALUE2) %]>

Putting it all together:  For message context B<CONTEXT>
the translation for a message in B<SINGULAR> and B<PLURAL>
is retrieved based on the argument B<COUNT>.  Possible placeholders
are expanded.

The function is a mixture of xgettext(), ngettext(), and
pgettext(), see above!

=item B<[% gtx.ngettext(SINGULAR, PLURAL, COUNT) %]>

Useless function, provided for completeness.  Use nxgettext()
instead, so that you can interpolate the value of B<COUNT>!

=item B<[% gtx.npgettext(CONTEXT, SINGULAR, PLURAL, COUNT) %]>

Useless function, provided for completeness.  Use npxgettext()
instead, so that you can interpolate the value of B<COUNT>!

=back

In fact, you have also all the keywords used for L</FILTERS>
available but those not listed here have such an odd ordering
of arguments that they are not listed here.

=head2 FILTERS

The entire gettext API is also exposed as a filter.  There are
two things to note here:

=over 4

=item *

When used as filters, you don't prefix the method names.  It'
s "gettext" not "Gettext.gettext" or "gtx.gettext()".

=item *

The filters with message contexts have rather strange names, for example:

    [% FILTER gettextp("greeting") %]
    Hello, world!
    [% END %]

    or 100 % equivalent:

    [% 'Hello, world!' | gettextp("greeting") %]

Why? The text between B<FILTER> and B<END> resp. the text
in front of the pipe symbol B<|> is always the first argument.
This plug-in therefore tries to make the first argument the
most significant one.  Nobody stops you from writing the
following:

    [% FILTER pgettext("Hello, world!") %]
    greeting
    [% END %]

    or again 100 % equivalent:

    [% 'greeting' | pgettext("Hello, world!") %]

It produces exactly the same results as above but it looks 
a little bit odd, doesn't it?

It would have been arguably better understandable to silently
reorder the arguments, when using the plug-in as a filter.
But it would break extraction of your strings with
L<xgettext-tt2> (L<Locale::XGettext::TT2>) because the string
extractor would then confuse the arguments.

But stay relaxed! Message contexts are rarely needed, and when
you need them, you have to live with this little weirdness.

In order to avoid confusion, those filters that would not have
the translatable string (in the singular form) where one would
expect it, are not documented here.

=back

You can use the following filters:

=over 4

=item B<[% STRING | gettext %]>

=item B<[% FILTER gettext %]STRING[% FILTER %]>

Retrieves the translation for B<STRING>.

=item B<[% STRING | xgettext(PLACEHOLDER1 =E<gt> VALUE1, PLACEHOLDER2 =E<gt> VALUE2, ...) %]>

=item B<[% FILTER xgettext(PLACEHOLDER1 =E<gt> VALUE1, PLACEHOLDER2 =E<gt> VALUE2, ...) %]STRING[% END %]>

Gets the translation for a string with placeholders and interpolates values
into it.  Placeholders have the format <{PLACEHOLDER}>.  For a literal
left curly brace you can use this hack:

    [% "String with {LBRACE}PLACEHOLDERS{RBRACE}" | xgettext(LBRACE => "{", RBRACE => "}") %]

=item B<[% STRING | gettextp(CONTEXT) %]>

=item B<[% FILTER gettextp(CONTEXT) %]STRING[% END %]>

Retrieves the translation for B<STRING> in context B<CONTEXT>.  You
should use message context to disambiguate identical strings that
require different translations depending on the context. See the 
docuemntation for pgettext() in L</FUNCTIONS> above for more details!

=item B<[% STRING | xgettextp(CONTEXT, STRING, PLACEHOLDER1 =E<gt> VALUE1, PLACEHOLDER2 =E<gt> VALUE2) %]>

=item B<[% FILTER xgettextp(CONTEXT, STRING, PLACEHOLDER1 =E<gt> VALUE1, PLACEHOLDER2 =E<gt> VALUE2) %]STRING[% END %]>

Get the translation for B<STRING> with placeholders in context
B<CONTEXT>.  This is a mixture of C<xgettext()> and C<pgettext()>
above.

=item B<[% SINGULAR | nxgettext(PLURAL, COUNT, PLACEHOLDER1 =E<gt> VALUE1, PLACEHOLDER2 =E<gt> VALUE2) %]>

=item B<[% FILTER nxgettext(PLURAL, COUNT, PLACEHOLDER1 =E<gt> VALUE1, PLACEHOLDER2 =E<gt> VALUE2) %]SINGULAR[% END %]>

Retrieves the translation for the string with the singular form
B<SINGULAR> and the plural from B<PLURAL>, both possibly
containing placeholders.  The correct form is picked based
upon the third argument B<COUNT>.

Example:

    [% "One document deleted" | nxgettext("{num} documents deleted"),
                                          count,
                                          num => count) %]

In English this will produce "42 documents deleted" if the variable
count has the value 42.  It will produce "One document deleted" if
the variable count has the value 1.

In other languages, the rules for plural forms may be a lot
simpler (for example Chinese, which has no plural) or a lot more 
complicated (for example Russian with two or Slovenian with even
3 plural forms).  Using ngettext() gives your translators the
chance to provide syntactically correct translations for these
cases.

=item B<[% SINGULAR | nxgettextp(PLURAL, COUNT, CONTEXT,
                                 PLACEHOLDER1 =E<gt> VALUE1,
                                 PLACEHOLDER2 =E<gt> VALUE2) %]>

=item B<[% FILTER nxgettextp(PLURAL, COUNT, CONTEXT,
                                 PLACEHOLDER1 =E<gt> VALUE1,
                                 PLACEHOLDER2 =E<gt> VALUE2) %]SINGULAR[% END %]>

Putting it all together:  For message context B<CONTEXT>
the translation for a message in B<SINGULAR> and B<PLURAL>
is retrieved based on the argument B<COUNT>.  Possible placeholders
are expanded.

The filter is a mixture of xgettext(), ngettext(), and
pgettext(), see above!

=item B<[% SINGULAR | ngettext(PLURAL, COUNT) %]>

=item B<[% FILTER ngettext(PLURAL, COUNT) %]SINGULAR[% END %]>

Useless filter, provided for completeness.  Use nxgettext()
instead, so that you can interpolate the value of B<COUNT>!

=item B<[% SINGULAR | ngettextp[(PLURAL, COUNT, CONTEXT) %]>

=item B<[% FILTER | ngettextp[(PLURAL, COUNT, CONTEXT) %]SINGULAR[% END %]>

Useless filter, provided for completeness.  Use nxgettextp()
instead, so that you can interpolate the value of B<COUNT>!

=item B<[% debug_locale %]>

The plug-in implicitly calls B<web_set_locale()> (see
L<Locale::Util>) if a language was specified in the B<USE> 
statement.  The function B<debug_locale()> gives you the return
value of the call for debugging purposes.  Example:

    [% USE gtx = Gettext('com.mydomain.www', de') %]
    
    Using locale [% debug_locale() %].

This way, you can determine whether setting the specified locale
actually worked.

=back

=head1 CLASS METHODS

=over 4

=item B<textdomains>

Returns a hash where the keys are the textdomains found in templates that
invoked the plug-in, and the values are the corresponding template file names.

The purpose of this method is to allow harvesting files that should be
processed by L<xgettext-tt2>.

If the template is either "input text" or "input file handle", the template
variable C<gettext_filename> - if existing - is assumed as the template
name.  Rationale: "input text" and "input file handle" are used by the
Template Toolkit as aliases, when reading from a scalar or a file handle.

=item B<resetTextdomains>

Resets the hash described above for B<textdomain()> to its initial, empty
state.

=back

=head1 COPYRIGHT

Copyright (C) 2016-2018 Guido Flohr (http://www.guido-flohr.net/).
License LGPLv3+: L<GNU General Public License version 3 or later|http://gnu.org/licenses/lgpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Copyright (C) 2016-2018 Guido Flohr <guido.flohr@cantanea.com>,
all rights reserved.

=head1 SEE ALSO

L<Template>, L<Template::Manual::Filters>, L<xgettext-tt2>, L<perl>