1use strict;
2use warnings;
3
4package Jifty::Plugin::I18N;
5use base 'Jifty::Plugin';
6
7=head1 NAME
8
9Jifty::Plugin::I18N - Additional i18n facility such as language selector
10
11=head1 SYNOPSIS
12
13# In your jifty config.yml under the framework section:
14
15  L10N:
16    PoDir: share/po
17    AllowedLang:
18      - en
19      - zh_tw
20  Plugins:
21    - I18N:
22        js: 1
23
24
25=head1 DESCRIPTION
26
27This plugin provides additional i18n facility to Jifty's core i18n
28features, such as compiling l10n lexicon for client side javascript,
29and a language selector action.
30
31You will still need to manually do the following to make client side l10n work:
32
33=over
34
35=item Extract strings from your js files into your po file
36
37  jifty po --dir share/web/static/js
38
39=item Generate js dictionary
40
41  jifty po --js
42
43=back
44
45=head2 init
46
47=cut
48
49__PACKAGE__->mk_accessors(qw(js));
50
51Jifty->web->add_javascript('loc.js');
52
53sub init {
54    my $self = shift;
55    return if $self->_pre_init;
56
57    my %opt  = @_;
58    $self->js( $opt{js} );
59
60    Jifty::Web->add_trigger(
61        name      => 'after_include_javascript',
62        callback  => sub { $self->_i18n_js(@_) },
63    ) if $self->js;
64}
65
66sub _i18n_js {
67    my $self = shift;
68
69    my $current_lang = Jifty::I18N->get_current_language || 'en';
70
71    # diagnosis for htf the client is requesting something not in allowed_lang.
72    my $allowed_lang = Jifty->config->framework('L10N')->{'AllowedLang'};
73    $allowed_lang = [defined $allowed_lang ? $allowed_lang : ()] unless ref($allowed_lang) eq 'ARRAY';
74
75    if (@$allowed_lang) {
76        my $allowed_regex = join '|', map {
77            my $it = $_;
78            $it =~ tr<-A-Z><_a-z>; # lc, and turn - to _
79            $it =~ tr<_a-z0-9><>cd;  # remove all but a-z0-9_
80            $it;
81        } @$allowed_lang;
82
83        unless ( $current_lang =~ /^$allowed_regex/) {
84            $self->log->error("user is requesting $current_lang which is not allowed");
85        }
86    }
87
88    if (
89        open my $fh,
90        '<:encoding(utf-8)',
91        Jifty::Util->absolute_path(
92            File::Spec->catdir(
93                Jifty->config->framework('Web')->{StaticRoot},
94                "js/dict/$current_lang.json"
95            )
96        )
97      )
98    {
99        local $/;
100        my $inline_dict = <$fh> || '{}';
101
102        # js l10n init
103        Jifty->web->out(
104            qq{<script type="text/javascript">
105Localization.dict_path = '/static/js/dict';
106Localization.dict = $inline_dict;
107</script>}
108        );
109
110    }
111    else {
112        $self->log->error("Can't find dictionary file $current_lang.json: $!");
113    }
114
115}
116
1171;
118