File Coverage

lib/Dancer2/Plugin/Multilang.pm
Criterion Covered Total %
statement 3 17 17.6
branch 0 2 0.0
condition n/a
subroutine 1 3 33.3
pod 0 1 0.0
total 4 23 17.3


line stmt bran cond sub pod time code
1             package Dancer2::Plugin::Multilang;
2             {
3             $Dancer2::Plugin::Multilang::VERSION = '1.1.2';
4             }
5 1     1   348182 use Dancer2::Plugin 0.156000;
  1         1695  
  1         5  
6              
7             register 'language' => sub {
8 0     0     my $dsl = shift;
9 0           return $dsl->app->request->params->{'multilang.lang'};
10             };
11              
12             on_plugin_import {
13             my $dsl = shift;
14             my $conf = plugin_setting();
15             my @managed_languages = @{$conf->{'languages'}};
16             $dsl->app->add_hook(
17             Dancer2::Core::Hook->new(name => 'before', code => sub {
18             my $default_language = $conf->{'default'};
19             my $match_string = "^\/(" . join('|', @managed_languages) . ")";
20             my $match_regexp = qr/$match_string/;
21             my $path = $dsl->app->request->path_info();
22             my $lang = '';
23             if ($path =~ $match_regexp)
24             {
25             $lang = $1;
26             }
27             if($lang eq '')
28             {
29             if($dsl->app->request->params->{'multilang.lang'})
30             {
31             $dsl->cookie('multilang.lang' => $dsl->param('multilang.lang'));
32             }
33             else
34             {
35             my $accepted_language = $dsl->app->request->header('Accept-Language') ?
36             wanted_language($dsl, $dsl->app->request->header('Accept-Language'), @managed_languages) :
37             '';
38             if($dsl->cookie('multilang.lang'))
39             {
40             $dsl->redirect("/" . $dsl->cookie('multilang.lang') . $path);
41             }
42             elsif($accepted_language ne '')
43             {
44             $dsl->redirect("/$accepted_language" . $path);
45             }
46             else
47             {
48             $dsl->redirect("/$default_language" . $path);
49             }
50             }
51             }
52             else
53             {
54             $path =~ s/$match_regexp//;
55             $dsl->forward($path, {'multilang.lang' => $lang}, undef);
56             }
57             })
58             );
59             $dsl->app->add_hook(
60             Dancer2::Core::Hook->new(name => 'engine.template.after_layout_render', code => sub {
61             my $content = shift;
62             my @managed_languages = @{$conf->{'languages'}};
63             if(my $selected_lan = $dsl->app->request->params->{'multilang.lang'})
64             {
65             for(@managed_languages)
66             {
67             my $lan = $_;
68             if($lan ne $selected_lan)
69             {
70             my $meta_for_lan = '\n";
71             $$content =~ s/<\/head>/$meta_for_lan<\/head>/;
72             }
73             }
74             }
75             })
76             );
77             for my $l( @managed_languages)
78             {
79             $dsl->any( ['get', 'post'] => "/" . $l . "/**", sub { $dsl->pass; });
80             $dsl->any( ['get', 'post'] => "/" . $l . "/", sub { $dsl->pass; });
81             }
82              
83             };
84              
85             sub wanted_language
86             {
87 0     0 0   my $dsl = shift;
88 0           my $header = shift;
89 0           my @managed_languages = @_;
90 0           my @lan_strings = split(',', $header);
91 0           for(@lan_strings)
92             {
93 0           my $str = $_;
94 0           $str =~ m/^(..?)(\-.+)?$/; #Only primary tag is considered
95 0           my $lan = $1;
96 0 0         if (grep {$_ eq $lan} @managed_languages) {
  0            
97 0           return $lan;
98             }
99             }
100 0           return '';
101             };
102              
103             register_plugin for_versions => [ 2 ];
104              
105             1;
106              
107             =encoding utf8
108              
109             =head1 NAME
110              
111             Dancer2::Plugin::Multilang - Dancer2 Plugin to create multilanguage sites
112              
113              
114             =head1 DESCRIPTION
115              
116             A plugin for Dancer2 to create multilanguage sites. In your app you can configure any route you want as /myroute/to/page.
117              
118             Plugin will make the app answer to /en/myroute/to/page or /it/myroute/to/page giving the language path to the route manager as a Dancer keyword.
119             It will also redirect navigation using information from the headers transmitted from the browser. Language change during navigation will be managed via cookie.
120              
121             Multilanguage SEO headers will be generated to give advice to the search engines about the language of the pages.
122              
123             =head1 SYNOPSIS
124              
125             # In your Dancer2 app,
126             use Dancer2::Plugin::Multilang
127              
128             #In your config.yml
129             plugins:
130             Multilang:
131             languages: ['it', 'en']
132             default: 'it'
133              
134             where languages is the array of all the languages managed and default is the response language if no information about language can be retrieved.
135              
136             #In the routes
137             get '/route/to/page' => sub {
138             if( language == 'en' )
139             {
140             /* english navigation */
141             }
142             elsif( language == 'it' )
143             {
144             /* italian navigation */
145             }
146             elsif...
147              
148             =head1 USAGE
149              
150             No language information has to be managed in route definition. Language path will be added transparently to your routes.
151              
152             language keyword can be used to retrieve language information inside the route manager.
153              
154             =head1 OPTIONS
155              
156             The options you can configure are:
157              
158             =over 4
159              
160             =item C (required)
161              
162             The array of the languages that will be managed.
163              
164             All the languages are two characters codes as in the primary tag defined by http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.10
165              
166             =item C (required)
167              
168             The default language that will be used when plugin can't guess desired one (or when desired one is not managed)
169              
170             =back
171              
172             =cut
173