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