File Coverage

blib/lib/Dancer/Plugin/SimpleLexicon.pm
Criterion Covered Total %
statement 97 106 91.5
branch 24 36 66.6
condition 9 20 45.0
subroutine 20 20 100.0
pod n/a
total 150 182 82.4


line stmt bran cond sub pod time code
1             package Dancer::Plugin::SimpleLexicon::Handler;
2 3     3   214708 use 5.010001;
  3         9  
  3         104  
3 3     3   13 use strict;
  3         5  
  3         72  
4 3     3   9 use warnings;
  3         12  
  3         68  
5 3     3   13 use base 'Locale::Maketext';
  3         3  
  3         1735  
6 3     3   29673 use Locale::Maketext::Lexicon;
  3         6620  
  3         18  
7              
8             sub import_po_file {
9 3     3   5 my ($self, $lang, $pofile) = @_;
10             # warn "$self, $lang, $pofile";
11 3         22 Locale::Maketext::Lexicon->import({
12             $lang => [Gettext => $pofile],
13             });
14             }
15              
16             1;
17              
18              
19             package Dancer::Plugin::SimpleLexicon;
20              
21 3     3   235 use 5.010001;
  3         8  
  3         77  
22 3     3   12 use strict;
  3         3  
  3         66  
23 3     3   12 use warnings;
  3         3  
  3         184  
24              
25             =head1 NAME
26              
27             Dancer::Plugin::SimpleLexicon - Tiny Dancer interface to Locale::Maketext::Lexicon
28              
29             =head1 VERSION
30              
31             Version 0.01
32              
33             =cut
34              
35             our $VERSION = '0.01';
36              
37              
38             =head1 SYNOPSIS
39              
40             In your configuration:
41              
42             plugins:
43             SimpleLexicon:
44             path: languages
45             session_name: lang
46             param_name: lang
47             var_name: lang
48             default: en
49             encoding: UTF-8
50             langs:
51             en: "US English"
52             de: "Deutsch"
53             nl: "Netherlands"
54             se: "Sweden"
55             it: "Italiano"
56              
57             In your module
58              
59             use Dancer ':syntax';
60             use Dancer::Plugin::SimpleLexicon;
61             var lang => 'it';
62             my $string = l('Hello %s', 'Marco');
63             # assuming languages/it.po have a translation for this, will return "Ciao Marco"
64              
65             =head1 SETTINGS
66              
67             This module is a tiny alternative to L. See
68             what it works best for you.
69              
70             Explanation of the settings.
71              
72             =head2 path
73              
74             The path, absolute or relative, to the C<.po> files. The C<.po> files
75             must be named as the defined language tags (see below).
76              
77             =head2 langs
78              
79             An array of keys/values with the language tag and the full name on the
80             language.
81              
82             Please note that if you define a language "it", the file
83             C B.
84              
85             =head2 param_name
86              
87             If specified, when determining the language, the module will try to
88             lookup the key in the request parameters (C).
89              
90             =head2 session_name
91              
92             The key of the C where to read and store the current language.
93             If not specified, the session is not touched.
94              
95             =head2 var_name
96              
97             The name of the Dancer C to read when determining the current language.
98              
99             =head2 default
100              
101             The value of the default language. If not specified, and the looking up
102             in the above values fails, no translation will be done.
103              
104             =head2 encoding
105              
106             The string returned by maketext will be decoded using
107             this encoding. By default is C.
108              
109             To disable the decoding, set it to C.
110              
111             =head1 EXPORT
112              
113             =head2 l($string, @args)
114              
115             Return the translation for $string. If optional arguments are
116             provided, pass the string to sprintf with the arguments.
117              
118             =head2 language
119              
120             Return the current language used, returning the long name of the
121             language as defined in the configuration.
122              
123             The priority set is follow: param, session, var, default. The first
124             wins, assuming it was defined in the config. Unclear if it's the right
125             thing to do. TODO: make this configurable or at runtime.
126              
127             =head2 set_language($language_tag)
128              
129             Set the current language to $language_tag, writing it into the
130             session, using the key specified in the C value.
131              
132             =head1 Dancer::Template::TemplateFlute integration
133              
134             In the configuration:
135              
136             engines:
137             template_flute:
138             i18n:
139             class: My::Lexicon
140             method: localize
141             plugins:
142             SimpleLexicon:
143             path: languages
144             session_name: lang
145             param_name: lang
146             var_name: lang
147             default: en
148             encoding: UTF-8
149             langs:
150             en: "US English"
151             de: "Deutsch"
152             nl: "Netherlands"
153             se: "Sweden"
154              
155             And write the tiny class My::Lexicon wit the following content:
156              
157             package My::Lexicon;
158             use Dancer ':syntax';
159             use Dancer::Plugin::SimpleLexicon;
160             use Encode;
161            
162             sub new {
163             my $class = shift;
164             my $self = {};
165             bless $self, $class;
166             }
167            
168             sub localize {
169             my ($self, $string) = @_;
170             my $translated = l($string);
171             return $translated;
172             }
173            
174             1;
175              
176              
177             =cut
178              
179             package Dancer::Plugin::SimpleLexicon;
180              
181              
182 3     3   11 use strict;
  3         4  
  3         59  
183 3     3   18 use warnings;
  3         5  
  3         56  
184 3     3   1356 use Dancer::Plugin;
  3         124523  
  3         215  
185 3     3   1112 use Dancer ':syntax';
  3         250486  
  3         17  
186 3     3   1866 use File::Spec::Functions qw/catfile/;
  3         1192  
  3         189  
187 3     3   29 use Encode;
  3         4  
  3         2037  
188              
189             my $Handlers;
190              
191             register l => \&_localize;
192              
193             register language => sub {
194 2     2   2865 my $lang = _determine_language();
195 2 50       5 return 'none found' unless $lang;
196 2         4 return plugin_setting->{langs}->{$lang};
197             };
198              
199             register set_language => sub {
200 1     1   735 my ($lang) = @_;
201 1 50       3 return unless $lang;
202 1 50       4 unless (plugin_setting->{langs}->{$lang}) {
203 0         0 error "Unknown language tag $lang";
204 0         0 return;
205             }
206 1 50       18 if (my $sn = plugin_setting->{session_name}) {
207 1         14 session $sn => $lang;
208             }
209             else {
210 0         0 error "No session_name specified in the configuration, couldn't set $lang";
211             }
212             };
213              
214             register_plugin;
215              
216             sub _init_handlers {
217 1     1   3 my $settings = plugin_setting;
218 1         10 my %handlers;
219             # debug to_dumper($settings);
220 1 50 33     10 if ($settings && $settings->{langs} && $settings->{path}) {
      33        
221 1         2 foreach my $lang (keys %{$settings->{langs}}) {
  1         4  
222 3         16 my $path = catfile($settings->{path}, $lang . ".po");
223 3 50       67 unless (-f $path) {
224 0         0 die "You defined the language $lang, but $path was not found!";
225             }
226 3         13 Dancer::Plugin::SimpleLexicon::Handler->import_po_file($lang, $path);
227 3         3721 my $handler = Dancer::Plugin::SimpleLexicon::Handler->get_handle($lang);
228 3 50       980 die "Couldn't get an handler out of $path!" unless $handler;
229 3         8 $handlers{$lang} = $handler;
230             }
231             }
232             else {
233 0         0 error "Missing configuration 'langs' or 'path' for " . __PACKAGE__;
234             }
235 1         3 $Handlers = \%handlers;
236             }
237              
238             sub _determine_language {
239 10     10   21 my $settings = plugin_setting;
240              
241             # try to see which language to use, starting from the more
242             # specific one to the more general one;
243              
244 10         91 my $lang;
245              
246 10 50       22 if ($settings->{param_name}) {
247             # wrap in eval, if we're out of a rout would crash
248 10         8 eval {
249 10         26 $lang = param($settings->{param_name});
250             # debug "Found $lang found in param";
251             }
252             }
253              
254 10 100 66     940 if (!$lang && $settings->{session_name}) {
255 2         6 $lang = session($settings->{session_name});
256             # debug "Found $lang found in session";
257             }
258              
259 10 100 66     560 if (!$lang && $settings->{var_name}) {
260 2         5 $lang = var($settings->{var_name});
261             # debug "Found $lang found in var";
262             }
263              
264 10 50 33     31 if (!$lang && $settings->{default}) {
265 0         0 $lang = $settings->{default};
266             # debug "using default";
267             }
268              
269 10         13 return $lang;
270             }
271              
272              
273             sub _localize {
274 8     8   13617 my ($string, @args) = @_;
275              
276             # initialize if not alredy done
277 8 100       20 unless ($Handlers) {
278 1         3 _init_handlers();
279             }
280              
281 8         13 my $settings = plugin_setting;
282 8         91 my $lang = _determine_language();
283              
284 8         10 my $default_string = $string;
285 8 100       16 if (@args) {
286 4         13 $default_string = sprintf($default_string, @args);
287             }
288              
289 8 50       16 unless ($lang) {
290 0         0 info "No valid configuration find for " . __PACKAGE__;
291 0         0 return $default_string;
292             }
293              
294             # get the handler
295 8         10 my $h = $Handlers->{$lang};
296 8 100       15 unless ($h) {
297             # warn "Couldn't get an handler for $lang!";
298 2         8 return $default_string;
299             }
300            
301              
302             # try to translate. If not so, return the string
303 6         6 my $translation;
304 6         6 eval { $translation = $h->maketext($string) };
  6         30  
305 6 50 33     309 unless (defined $translation and $translation =~ /\S/) {
306 0         0 return $default_string;
307             }
308              
309             # decode the string
310 6   50     22 my $enc = $settings->{encoding} || 'UTF-8';
311 6 50       11 unless ($enc eq 'raw') {
312 6         11 $translation = decode($enc, $translation);
313             }
314              
315 6 100       173 if (@args) {
316 3         16 return sprintf($translation, @args);
317             }
318             else {
319 3         12 return $translation;
320             }
321             }
322              
323              
324             =head1 AUTHOR
325              
326             Marco Pessotto, C<< >>
327              
328             =head1 BUGS
329              
330             Please report any bugs or feature requests to C, or through
331             the web interface at L. I will be notified, and then you'll
332             automatically be notified of progress on your bug as I make changes.
333              
334              
335              
336              
337             =head1 SUPPORT
338              
339             You can find documentation for this module with the perldoc command.
340              
341             perldoc Dancer::Plugin::SimpleLexicon
342              
343              
344             You can also look for information at:
345              
346             =over 4
347              
348             =item * RT: CPAN's request tracker (report bugs here)
349              
350             L
351              
352             =item * AnnoCPAN: Annotated CPAN documentation
353              
354             L
355              
356             =item * CPAN Ratings
357              
358             L
359              
360             =item * Search CPAN
361              
362             L
363              
364             =back
365              
366              
367             =head1 ACKNOWLEDGEMENTS
368              
369              
370             =head1 LICENSE AND COPYRIGHT
371              
372             Copyright 2014 Marco Pessotto.
373              
374             This program is free software; you can redistribute it and/or modify it
375             under the terms of either: the GNU General Public License as published
376             by the Free Software Foundation; or the Artistic License.
377              
378             See L for more information.
379              
380              
381             =cut
382              
383             1; # End of Dancer::Plugin::SimpleLexicon