File: Template.pod

package info (click to toggle)
liblog-report-lexicon-perl 1.15-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 452 kB
  • sloc: perl: 2,671; makefile: 9
file content (295 lines) | stat: -rw-r--r-- 8,193 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
=encoding utf8

=head1 NAME

Log::Report::Extract::Template - collect translatable strings from template files

=head1 INHERITANCE

 Log::Report::Extract::Template
   is a Log::Report::Extract

=head1 SYNOPSIS

 # First use of this module: extract msgids from various kinds
 # of text-files, usually web templates.
 # See script "xgettext-perl" for standard wrapper script

 my $extr = Log::Report::Extract::Template->new
   ( lexicon => '/usr/share/locale'
   , domain  => 'my-web-site'
   , pattern => 'TT2-loc'
   );
 $extr->process('website/page.html');  # many times
 $extr->showStats;
 $extr->write;

 # Second use: connect to Template::Toolkit
 # See DETAILS chapter below

 [% loc("Greetings {name},", name => client.name) %]
 [% | loc(name => client.name) %]Greetings {name}[% END %]
 [% 'Greetings {name}' | loc(name => client.name) %]

=head1 DESCRIPTION

This module helps maintaining the POT files which list translatable
strings from template files (or other flat text files) by updating the
list of message-ids which are kept in them.

After initiation, the L<process()|Log::Report::Extract::Template/"Processors"> method needs to be called for each file
in the domain  and the existing PO files will get updated accordingly.

If no translations exist yet, one C<$textdomain.po> file will be
created as point to start.  Copy that file into C<$textdomain/$lang.po>

Extends L<"DESCRIPTION" in Log::Report::Extract|Log::Report::Extract/"DESCRIPTION">.
 
=head1 METHODS

Extends L<"METHODS" in Log::Report::Extract|Log::Report::Extract/"METHODS">.
 
=head2 Constructors

Extends L<"Constructors" in Log::Report::Extract|Log::Report::Extract/"Constructors">.
 
=over 4

=item Log::Report::Extract::Template-E<gt>B<new>(%options)

 -Option --Defined in          --Default
  charset  Log::Report::Extract  'utf-8'
  domain                         <required>
  lexicon  Log::Report::Extract  <required>
  pattern                        <undef>

=over 2

=item charset => STRING

=item domain => DOMAIN

There is no syntax for specifying domains in templates (yet), so you
must be explicit about the collection we are making now.

=item lexicon => DIRECTORY

=item pattern => PREDEFINED|CODE

See the DETAILS section below for a detailed explenation.

=back

=back

=head2 Accessors

Extends L<"Accessors" in Log::Report::Extract|Log::Report::Extract/"Accessors">.
 
=over 4

=item $obj-E<gt>B<addPot>($domain, $pot, %options)

Inherited, see L<Log::Report::Extract/"Accessors">

=item $obj-E<gt>B<charset>()

Inherited, see L<Log::Report::Extract/"Accessors">

=item $obj-E<gt>B<domain>()

=item $obj-E<gt>B<domains>()

Inherited, see L<Log::Report::Extract/"Accessors">

=item $obj-E<gt>B<index>()

Inherited, see L<Log::Report::Extract/"Accessors">

=item $obj-E<gt>B<pattern>()

=item $obj-E<gt>B<pots>($domain)

Inherited, see L<Log::Report::Extract/"Accessors">

=back

=head2 Processors

Extends L<"Processors" in Log::Report::Extract|Log::Report::Extract/"Processors">.
 
=over 4

=item $obj-E<gt>B<cleanup>(%options)

Inherited, see L<Log::Report::Extract/"Processors">

=item $obj-E<gt>B<process>($filename, %options)

Update the domains mentioned in the $filename.  All textdomains defined
in the file will get updated automatically, but not written before
all files where processed.

 -Option --Default
  charset  'utf-8'
  pattern  <from new(pattern)>

=over 2

=item charset => STRING

The character encoding used in this template file.

=item pattern => PREDEFINED|CODE

Read the DETAILS section about this.

=back

=item $obj-E<gt>B<showStats>( [$domains] )

Inherited, see L<Log::Report::Extract/"Processors">

=item $obj-E<gt>B<store>( $domain, $filename, $linenr, $context, $msg, [$msg_plural] )

Inherited, see L<Log::Report::Extract/"Processors">

=item $obj-E<gt>B<write>( [$domain] )

Inherited, see L<Log::Report::Extract/"Processors">

=back

=head1 DETAILS

=head2 Scan Patterns

Various template systems use different conventions for denoting strings
to be translated.

=head3 Predefined for Template-Toolkit

There is not a single convention for translations in C<Template-Toolkit>
(see Template), so you need to specify which version TT you use and
which function name you want to use.  In extreme cases, you may even build
separate translation tables by simply providing using functions.

For instance

   pattern => 'TT2-loc'

will scan for

  [% loc("msgid", key => value, ...) %]
  [% loc('msgid', key => value, ...) %]
  [% loc("msgid|plural", count, key => value, ...) %]
 
  [% INCLUDE
       title = loc('something')
   %]
 
  [% | loc(n => name) %]hi {n}[% END %]
  [% 'hi {n}' | loc(n => name) %]

For TT1, the brackets can either be '[%...%]' or '%%...%%'.  The function
name is treated case-sensitive.  Some people prefer 'l()' or 'L()'.

The code needed

  # during initiation of the webserver, once in your script (before fork)
  my $lexicons   = 'some-directory-for-translation-tables';
  my $translator = Log::Report::Translator::POT->new(lexicons => $lexicons);
  my $domain     = textdomain $textdomain;
  $domain->configure(translator => $translator);

  # your standard template driver
  sub handler {
     ...
     my $vars      = { ...all kinds of values... };
     $vars->{loc}  = \&translate;           # <--- this is extra

     my $output    = '';
     my $templater = Template->new(...);
     $templater->process($template_fn, $vars, \$output);
     print $output;
  }

  # anywhere in the same file
  sub translate {
    my $textdomain = ...;   # your choice when running xgettext-perl
    my $lang       = ...;   # how do you figure that out?
    my $msg = Log::Report::Message->fromTemplateToolkit($textdomain, @_);
    $msg->toString($lang);
  }

To generate the pod tables, run in the shell something like

  xgettext-perl -p $lexicons --template TT2-loc \
      --domain $textdomain  $templates_dir

If you want to implement your own extractor --to avoid C<xgettext-perl>--
you need to run something like this:

  my $extr = Log::Report::Extract::Template->new
    ( lexicon => $output
    , charset => 'utf-8'
    , domain  => $domain
    , pattern => 'TT2-loc'
    );
  $extr->process($_) for @filenames;
  $extr->write;

=head2 Use in combination with contexts

This example extends the previous with using context sensitive translations,
as implemented by L<Log::Report::Translator::Context|Log::Report::Translator::Context>.

Let's say that the translation of some of the sentences on the website depend
on the gender of the addressed person.  An example of the use in a TT2
template:

  [% loc("{name<gender} forgot his key", name => person.name) %]

The extraction script F<xgettext-perl> will expand this into two records
in the PO file, respectively with msgctxt attribute 'gender=male' and
'gender=female'.

When your PO-files are not generated by 'xgettext-perl', you do not need
a separate domain configuration file:

  $domain->configure
    ( context_rules => +{gender => ['male','female']}
    , translator    => $translator
    );

When your PO-files are generated by 'xgettext-perl', you need to share
the context-rules between that msgid extractor and your runtime code. That
same file needs to be passed with the 'domain' parameter to the script.

  # add context_rules either explicit or via 'config' filename
  $domain->configure
    ( config     => 'my/own/$domain.conf'
    , translator => $translator
    );

Now, when you generate the pages, you need to set-up the right context.
In this case, we set-up the gender of the person who gets addressed.
(The name 'gender' is good for examples, but quite non-descriptive.
Maybe 'user_gender' is more maintainable)

  $domain->setContext( +{gender => 'male'} );  # or ('gender=male')
  $domain->setContext( "gender=male" );        # same

=head1 SEE ALSO

This module is part of Log-Report-Lexicon distribution version 1.12,
built on April 18, 2025. Website: F<http://perl.overmeer.net/CPAN/>

=head1 LICENSE

Copyrights 2007-2025 by [Mark Overmeer <markov@cpan.org>]. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>