View | Details | Raw Unified | Return to bug 15395
Collapse All | Expand All

(-)a/Koha/I18N.pm (-41 / +63 lines)
Lines 26-31 use C4::Context; Link Here
26
use Encode;
26
use Encode;
27
use Locale::Util qw(set_locale);
27
use Locale::Util qw(set_locale);
28
use Locale::Messages qw(:locale_h :libintl_h nl_putenv);
28
use Locale::Messages qw(:locale_h :libintl_h nl_putenv);
29
use Koha::Cache::Memory::Lite;
29
30
30
use parent 'Exporter';
31
use parent 'Exporter';
31
our @EXPORT = qw(
32
our @EXPORT = qw(
Lines 44-98 our @EXPORT = qw( Link Here
44
    N__np
45
    N__np
45
);
46
);
46
47
47
my $textdomain;
48
our $textdomain = 'Koha';
49
50
sub init {
51
    my $cache = Koha::Cache::Memory::Lite->get_instance();
52
    my $cache_key = 'i18n:initialized';
53
    unless ($cache->get_from_cache($cache_key)) {
54
        my $langtag = C4::Languages::getlanguage;
55
        my @subtags = split /-/, $langtag;
56
        my ($language, $region) = @subtags;
57
        if ($region && length $region == 4) {
58
            $region = $subtags[2];
59
        }
60
        my $locale = set_locale(LC_ALL, $language, $region, 'utf-8');
61
        unless ($locale) {
62
            set_locale(LC_MESSAGES, '');
63
            Locale::Messages->select_package('gettext_pp');
64
            $locale = $language;
65
            if ($region) {
66
                $locale .= '_' . $region;
67
            }
68
            nl_putenv("LANGUAGE=$locale");
69
            nl_putenv("LANG=$locale");
70
            nl_putenv('OUTPUT_CHARSET=utf-8');
71
        }
48
72
49
BEGIN {
73
        my $directory = _base_directory();
50
    $textdomain = 'Koha';
74
        textdomain($textdomain);
75
        bindtextdomain($textdomain, $directory);
51
76
52
    my $langtag = C4::Languages::getlanguage;
77
        $cache->set_in_cache($cache_key, 1);
53
    my @subtags = split /-/, $langtag;
54
    my ($language, $region) = @subtags;
55
    if ($region && length $region == 4) {
56
        $region = $subtags[2];
57
    }
58
    my $locale = set_locale(LC_ALL, $language, $region, 'utf-8');
59
    unless ($locale) {
60
        set_locale(LC_MESSAGES, 'C');
61
        Locale::Messages->select_package('gettext_pp');
62
        $locale = $language;
63
        if ($region) {
64
            $locale .= '_' . $region;
65
        }
66
        nl_putenv("LANGUAGE=$locale");
67
        nl_putenv("LANG=$locale");
68
        nl_putenv('OUTPUT_CHARSET=utf-8');
69
    }
78
    }
70
71
    my $directory = C4::Context->config('intranetdir') . '/misc/translator/po';
72
    textdomain($textdomain);
73
    bindtextdomain($textdomain, $directory);
74
}
79
}
75
80
76
sub __ {
81
sub __ {
77
    my ($msgid) = @_;
82
    my ($msgid) = @_;
78
    my $text = dgettext($textdomain, $msgid);
83
79
    return __decode($text);
84
    return _gettext(\&gettext, [ $msgid ]);
80
}
85
}
81
86
82
sub __x {
87
sub __x {
83
    my ($msgid, %vars) = @_;
88
    my ($msgid, %vars) = @_;
84
    return __expand(__($msgid), %vars);
89
90
    return _gettext(\&gettext, [ $msgid ], %vars);
85
}
91
}
86
92
87
sub __n {
93
sub __n {
88
    my ($msgid, $msgid_plural, $count) = @_;
94
    my ($msgid, $msgid_plural, $count) = @_;
89
    my $text = dngettext($textdomain, $msgid, $msgid_plural, $count);
95
90
    return __decode($text);
96
    return _gettext(\&ngettext, [ $msgid, $msgid_plural, $count ]);
91
}
97
}
92
98
93
sub __nx {
99
sub __nx {
94
    my ($msgid, $msgid_plural, $count, %vars) = @_;
100
    my ($msgid, $msgid_plural, $count, %vars) = @_;
95
    return __expand(__n($msgid, $msgid_plural, $count), %vars);
101
102
    return _gettext(\&ngettext, [ $msgid, $msgid_plural, $count ], %vars);
96
}
103
}
97
104
98
sub __xn {
105
sub __xn {
Lines 101-124 sub __xn { Link Here
101
108
102
sub __p {
109
sub __p {
103
    my ($msgctxt, $msgid) = @_;
110
    my ($msgctxt, $msgid) = @_;
104
    my $text = dpgettext($textdomain, $msgctxt, $msgid);
111
105
    return __decode($text);
112
    return _gettext(\&pgettext, [ $msgctxt, $msgid ]);
106
}
113
}
107
114
108
sub __px {
115
sub __px {
109
    my ($msgctxt, $msgid, %vars) = @_;
116
    my ($msgctxt, $msgid, %vars) = @_;
110
    return __expand(__p($msgctxt, $msgid), %vars);
117
118
    return _gettext(\&pgettext, [ $msgctxt, $msgid ], %vars);
111
}
119
}
112
120
113
sub __np {
121
sub __np {
114
    my ($msgctxt, $msgid, $msgid_plural, $count) = @_;
122
    my ($msgctxt, $msgid, $msgid_plural, $count) = @_;
115
    my $text = dnpgettext($textdomain, $msgctxt, $msgid, $msgid_plural, $count);
123
116
    return __decode($text);
124
    return _gettext(\&npgettext, [ $msgctxt, $msgid, $msgid_plural, $count ]);
117
}
125
}
118
126
119
sub __npx {
127
sub __npx {
120
    my ($msgctxt, $msgid, $msgid_plural, $count, %vars) = @_;
128
    my ($msgctxt, $msgid, $msgid_plural, $count, %vars) = @_;
121
    return __expand(__np($msgctxt, $msgid, $msgid_plural, $count), %vars);
129
130
    return _gettext(\&npgettext, [ $msgctxt, $msgid, $msgid_plural, $count], %vars);
122
}
131
}
123
132
124
sub N__ {
133
sub N__ {
Lines 137-143 sub N__np { Link Here
137
    return @_;
146
    return @_;
138
}
147
}
139
148
140
sub __expand {
149
sub _base_directory {
150
    return C4::Context->config('intranetdir') . '/misc/translator/po';
151
}
152
153
sub _gettext {
154
    my ($sub, $args, %vars) = @_;
155
156
    init();
157
158
    my $text = Encode::decode_utf8($sub->(@$args));
159
    if (%vars) {
160
        $text = _expand($text, %vars);
161
    }
162
163
    return $text;
164
}
165
166
sub _expand {
141
    my ($text, %vars) = @_;
167
    my ($text, %vars) = @_;
142
168
143
    my $re = join '|', map { quotemeta $_ } keys %vars;
169
    my $re = join '|', map { quotemeta $_ } keys %vars;
Lines 146-153 sub __expand { Link Here
146
    return $text;
172
    return $text;
147
}
173
}
148
174
149
sub __decode {
150
    return Encode::decode_utf8(shift);
151
}
152
153
1;
175
1;
(-)a/t/Koha/I18N.t (+58 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
use Test::More tests => 35;
5
use Test::MockModule;
6
use FindBin qw($Bin);
7
use Encode;
8
9
BEGIN {
10
    use_ok('Koha::I18N');
11
}
12
13
my $koha_i18n = Test::MockModule->new('Koha::I18N');
14
$koha_i18n->mock('_base_directory', sub { "$Bin/I18N/po" });
15
16
my $c4_languages = Test::MockModule->new('C4::Languages');
17
$c4_languages->mock('getlanguage', sub { 'xx-XX' });
18
19
my @tests = (
20
    [ __('test') => 'test ツ' ],
21
    [ __x('Hello {name}', name => 'World') => 'Hello World ツ' ],
22
    [ __n('Singular', 'Plural', 0) => 'Zero ツ' ],
23
    [ __n('Singular', 'Plural', 1) => 'Singular ツ' ],
24
    [ __n('Singular', 'Plural', 2) => 'Plural ツ' ],
25
    [ __n('Singular', 'Plural', 3) => 'Plural ツ' ],
26
    [ __nx('one item', '{count} items', 0, count => 0) => 'no item ツ' ],
27
    [ __nx('one item', '{count} items', 1, count => 1) => 'one item ツ' ],
28
    [ __nx('one item', '{count} items', 2, count => 2) => '2 items ツ' ],
29
    [ __nx('one item', '{count} items', 3, count => 3) => '3 items ツ' ],
30
    [ __xn('one item', '{count} items', 0, count => 0) => 'no item ツ' ],
31
    [ __xn('one item', '{count} items', 1, count => 1) => 'one item ツ' ],
32
    [ __xn('one item', '{count} items', 2, count => 2) => '2 items ツ' ],
33
    [ __xn('one item', '{count} items', 3, count => 3) => '3 items ツ' ],
34
    [ __p('biblio', 'title') => 'title (biblio) ツ' ],
35
    [ __p('patron', 'title') => 'title (patron) ツ' ],
36
    [ __px('biblio', 'Remove item {id}', id => 42) => 'Remove item 42 (biblio) ツ' ],
37
    [ __px('list', 'Remove item {id}', id => 42) => 'Remove item 42 (list) ツ' ],
38
    [ __np('ctxt1', 'singular', 'plural', 0) => 'zero (ctxt1) ツ' ],
39
    [ __np('ctxt1', 'singular', 'plural', 1) => 'singular (ctxt1) ツ' ],
40
    [ __np('ctxt1', 'singular', 'plural', 2) => 'plural (ctxt1) ツ' ],
41
    [ __np('ctxt1', 'singular', 'plural', 3) => 'plural (ctxt1) ツ' ],
42
    [ __np('ctxt2', 'singular', 'plural', 0) => 'zero (ctxt2) ツ' ],
43
    [ __np('ctxt2', 'singular', 'plural', 1) => 'singular (ctxt2) ツ' ],
44
    [ __np('ctxt2', 'singular', 'plural', 2) => 'plural (ctxt2) ツ' ],
45
    [ __np('ctxt2', 'singular', 'plural', 3) => 'plural (ctxt2) ツ' ],
46
    [ __npx('biblio', 'one item', '{count} items', 0, count => 0) => 'no item (biblio) ツ' ],
47
    [ __npx('biblio', 'one item', '{count} items', 1, count => 1) => 'one item (biblio) ツ' ],
48
    [ __npx('biblio', 'one item', '{count} items', 2, count => 2) => '2 items (biblio) ツ' ],
49
    [ __npx('biblio', 'one item', '{count} items', 3, count => 3) => '3 items (biblio) ツ' ],
50
    [ __npx('list', 'one item', '{count} items', 0, count => 0) => 'no item (list) ツ' ],
51
    [ __npx('list', 'one item', '{count} items', 1, count => 1) => 'one item (list) ツ' ],
52
    [ __npx('list', 'one item', '{count} items', 2, count => 2) => '2 items (list) ツ' ],
53
    [ __npx('list', 'one item', '{count} items', 3, count => 3) => '3 items (list) ツ' ],
54
);
55
56
foreach my $test (@tests) {
57
    is($test->[0], decode_utf8($test->[1]), $test->[1]);
58
}
(-)a/t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.po (-1 / +81 lines)
Line 0 Link Here
0
- 
1
# PO file for tests
2
# Copyright (C) 2017 BibLibre
3
# This file is distributed under the same license as the Koha package.
4
# Julian Maurice <julian.maurice@biblibre.com, 2017.
5
#
6
#, fuzzy
7
msgid ""
8
msgstr ""
9
"Project-Id-Version: Koha\n"
10
"Report-Msgid-Bugs-To: \n"
11
"POT-Creation-Date: 2017-04-10 14:03+0200\n"
12
"PO-Revision-Date: 2017-04-10 14:03+0200\n"
13
"Last-Translator: Julian Maurice <julian.maurice@biblibre.com>\n"
14
"Language-Team: xx <xx@li.org>\n"
15
"Language: xx_XX\n"
16
"MIME-Version: 1.0\n"
17
"Content-Type: text/plain; charset=UTF-8\n"
18
"Content-Transfer-Encoding: 8bit\n"
19
"Plural-Forms: nplurals=3; plural=(n==0 ? 0 : n==1 ? 1 : 2);\n"
20
21
msgid "test"
22
msgstr "test ツ"
23
24
msgid "Hello {name}"
25
msgstr "Hello {name} ツ"
26
27
msgid "Singular"
28
msgid_plural "Plural"
29
msgstr[0] "Zero ツ"
30
msgstr[1] "Singular ツ"
31
msgstr[2] "Plural ツ"
32
33
msgid "one item"
34
msgid_plural "{count} items"
35
msgstr[0] "no item ツ"
36
msgstr[1] "one item ツ"
37
msgstr[2] "{count} items ツ"
38
39
msgctxt "biblio"
40
msgid "title"
41
msgstr "title (biblio) ツ"
42
43
msgctxt "patron"
44
msgid "title"
45
msgstr "title (patron) ツ"
46
47
msgctxt "biblio"
48
msgid "Remove item {id}"
49
msgstr "Remove item {id} (biblio) ツ"
50
51
msgctxt "list"
52
msgid "Remove item {id}"
53
msgstr "Remove item {id} (list) ツ"
54
55
msgctxt "ctxt1"
56
msgid "singular"
57
msgid_plural "plural"
58
msgstr[0] "zero (ctxt1) ツ"
59
msgstr[1] "singular (ctxt1) ツ"
60
msgstr[2] "plural (ctxt1) ツ"
61
62
msgctxt "ctxt2"
63
msgid "singular"
64
msgid_plural "plural"
65
msgstr[0] "zero (ctxt2) ツ"
66
msgstr[1] "singular (ctxt2) ツ"
67
msgstr[2] "plural (ctxt2) ツ"
68
69
msgctxt "biblio"
70
msgid "one item"
71
msgid_plural "{count} items"
72
msgstr[0] "no item (biblio) ツ"
73
msgstr[1] "one item (biblio) ツ"
74
msgstr[2] "{count} items (biblio) ツ"
75
76
msgctxt "list"
77
msgid "one item"
78
msgid_plural "{count} items"
79
msgstr[0] "no item (list) ツ"
80
msgstr[1] "one item (list) ツ"
81
msgstr[2] "{count} items (list) ツ"

Return to bug 15395