Bugzilla – Attachment 62332 Details for
Bug 15395
Internationalization: plural forms, context, and more
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 15395: Make Koha::I18N work with Plack + add tests
Bug-15395-Make-KohaI18N-work-with-Plack--add-tests.patch (text/plain), 12.08 KB, created by
Marc Véron
on 2017-04-18 19:51:42 UTC
(
hide
)
Description:
Bug 15395: Make Koha::I18N work with Plack + add tests
Filename:
MIME Type:
Creator:
Marc Véron
Created:
2017-04-18 19:51:42 UTC
Size:
12.08 KB
patch
obsolete
>From 839dce0ca136e4f88d0501e8b54df4e7b6f37e53 Mon Sep 17 00:00:00 2001 >From: Julian Maurice <julian.maurice@biblibre.com> >Date: Mon, 10 Apr 2017 18:29:12 +0200 >Subject: [PATCH] Bug 15395: Make Koha::I18N work with Plack + add tests >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Language detection was done in a BEGIN block so it was not working correctly >with Plack. This is now done when the first translation is requested. > >This patch also fixes a bug when set_locale(LC_ALL, ...) fails for some reasons >(locale is not installed system-wide for example). > >And finally, add some unit tests > >Test plan: >1. prove t/Koha/I18N.t >2. Replay the previous test plans with plack enabled > >Signed-off-by: Marc Véron <veron@veron.ch> >--- > Koha/I18N.pm | 104 +++++++++++++++++++------------ > t/Koha/I18N.t | 58 +++++++++++++++++ > t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.mo | Bin 0 -> 1370 bytes > t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.po | 81 ++++++++++++++++++++++++ > 4 files changed, 202 insertions(+), 41 deletions(-) > create mode 100755 t/Koha/I18N.t > create mode 100644 t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.mo > create mode 100644 t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.po > >diff --git a/Koha/I18N.pm b/Koha/I18N.pm >index 56d48d8..236454c 100644 >--- a/Koha/I18N.pm >+++ b/Koha/I18N.pm >@@ -26,6 +26,7 @@ use C4::Context; > use Encode; > use Locale::Util qw(set_locale); > use Locale::Messages qw(:locale_h :libintl_h nl_putenv); >+use Koha::Cache::Memory::Lite; > > use parent 'Exporter'; > our @EXPORT = qw( >@@ -44,55 +45,61 @@ our @EXPORT = qw( > N__np > ); > >-my $textdomain; >+our $textdomain = 'Koha'; >+ >+sub init { >+ my $cache = Koha::Cache::Memory::Lite->get_instance(); >+ my $cache_key = 'i18n:initialized'; >+ unless ($cache->get_from_cache($cache_key)) { >+ my $langtag = C4::Languages::getlanguage; >+ my @subtags = split /-/, $langtag; >+ my ($language, $region) = @subtags; >+ if ($region && length $region == 4) { >+ $region = $subtags[2]; >+ } >+ my $locale = set_locale(LC_ALL, $language, $region, 'utf-8'); >+ unless ($locale) { >+ set_locale(LC_MESSAGES, ''); >+ Locale::Messages->select_package('gettext_pp'); >+ $locale = $language; >+ if ($region) { >+ $locale .= '_' . $region; >+ } >+ nl_putenv("LANGUAGE=$locale"); >+ nl_putenv("LANG=$locale"); >+ nl_putenv('OUTPUT_CHARSET=utf-8'); >+ } > >-BEGIN { >- $textdomain = 'Koha'; >+ my $directory = _base_directory(); >+ textdomain($textdomain); >+ bindtextdomain($textdomain, $directory); > >- my $langtag = C4::Languages::getlanguage; >- my @subtags = split /-/, $langtag; >- my ($language, $region) = @subtags; >- if ($region && length $region == 4) { >- $region = $subtags[2]; >- } >- my $locale = set_locale(LC_ALL, $language, $region, 'utf-8'); >- unless ($locale) { >- set_locale(LC_MESSAGES, 'C'); >- Locale::Messages->select_package('gettext_pp'); >- $locale = $language; >- if ($region) { >- $locale .= '_' . $region; >- } >- nl_putenv("LANGUAGE=$locale"); >- nl_putenv("LANG=$locale"); >- nl_putenv('OUTPUT_CHARSET=utf-8'); >+ $cache->set_in_cache($cache_key, 1); > } >- >- my $directory = C4::Context->config('intranetdir') . '/misc/translator/po'; >- textdomain($textdomain); >- bindtextdomain($textdomain, $directory); > } > > sub __ { > my ($msgid) = @_; >- my $text = dgettext($textdomain, $msgid); >- return __decode($text); >+ >+ return _gettext(\&gettext, [ $msgid ]); > } > > sub __x { > my ($msgid, %vars) = @_; >- return __expand(__($msgid), %vars); >+ >+ return _gettext(\&gettext, [ $msgid ], %vars); > } > > sub __n { > my ($msgid, $msgid_plural, $count) = @_; >- my $text = dngettext($textdomain, $msgid, $msgid_plural, $count); >- return __decode($text); >+ >+ return _gettext(\&ngettext, [ $msgid, $msgid_plural, $count ]); > } > > sub __nx { > my ($msgid, $msgid_plural, $count, %vars) = @_; >- return __expand(__n($msgid, $msgid_plural, $count), %vars); >+ >+ return _gettext(\&ngettext, [ $msgid, $msgid_plural, $count ], %vars); > } > > sub __xn { >@@ -101,24 +108,26 @@ sub __xn { > > sub __p { > my ($msgctxt, $msgid) = @_; >- my $text = dpgettext($textdomain, $msgctxt, $msgid); >- return __decode($text); >+ >+ return _gettext(\&pgettext, [ $msgctxt, $msgid ]); > } > > sub __px { > my ($msgctxt, $msgid, %vars) = @_; >- return __expand(__p($msgctxt, $msgid), %vars); >+ >+ return _gettext(\&pgettext, [ $msgctxt, $msgid ], %vars); > } > > sub __np { > my ($msgctxt, $msgid, $msgid_plural, $count) = @_; >- my $text = dnpgettext($textdomain, $msgctxt, $msgid, $msgid_plural, $count); >- return __decode($text); >+ >+ return _gettext(\&npgettext, [ $msgctxt, $msgid, $msgid_plural, $count ]); > } > > sub __npx { > my ($msgctxt, $msgid, $msgid_plural, $count, %vars) = @_; >- return __expand(__np($msgctxt, $msgid, $msgid_plural, $count), %vars); >+ >+ return _gettext(\&npgettext, [ $msgctxt, $msgid, $msgid_plural, $count], %vars); > } > > sub N__ { >@@ -137,7 +146,24 @@ sub N__np { > return @_; > } > >-sub __expand { >+sub _base_directory { >+ return C4::Context->config('intranetdir') . '/misc/translator/po'; >+} >+ >+sub _gettext { >+ my ($sub, $args, %vars) = @_; >+ >+ init(); >+ >+ my $text = Encode::decode_utf8($sub->(@$args)); >+ if (%vars) { >+ $text = _expand($text, %vars); >+ } >+ >+ return $text; >+} >+ >+sub _expand { > my ($text, %vars) = @_; > > my $re = join '|', map { quotemeta $_ } keys %vars; >@@ -146,8 +172,4 @@ sub __expand { > return $text; > } > >-sub __decode { >- return Encode::decode_utf8(shift); >-} >- > 1; >diff --git a/t/Koha/I18N.t b/t/Koha/I18N.t >new file mode 100755 >index 0000000..a657b1e >--- /dev/null >+++ b/t/Koha/I18N.t >@@ -0,0 +1,58 @@ >+#!/usr/bin/perl >+ >+use Modern::Perl; >+use Test::More tests => 35; >+use Test::MockModule; >+use FindBin qw($Bin); >+use Encode; >+ >+BEGIN { >+ use_ok('Koha::I18N'); >+} >+ >+my $koha_i18n = Test::MockModule->new('Koha::I18N'); >+$koha_i18n->mock('_base_directory', sub { "$Bin/I18N/po" }); >+ >+my $c4_languages = Test::MockModule->new('C4::Languages'); >+$c4_languages->mock('getlanguage', sub { 'xx-XX' }); >+ >+my @tests = ( >+ [ __('test') => 'test ã' ], >+ [ __x('Hello {name}', name => 'World') => 'Hello World ã' ], >+ [ __n('Singular', 'Plural', 0) => 'Zero ã' ], >+ [ __n('Singular', 'Plural', 1) => 'Singular ã' ], >+ [ __n('Singular', 'Plural', 2) => 'Plural ã' ], >+ [ __n('Singular', 'Plural', 3) => 'Plural ã' ], >+ [ __nx('one item', '{count} items', 0, count => 0) => 'no item ã' ], >+ [ __nx('one item', '{count} items', 1, count => 1) => 'one item ã' ], >+ [ __nx('one item', '{count} items', 2, count => 2) => '2 items ã' ], >+ [ __nx('one item', '{count} items', 3, count => 3) => '3 items ã' ], >+ [ __xn('one item', '{count} items', 0, count => 0) => 'no item ã' ], >+ [ __xn('one item', '{count} items', 1, count => 1) => 'one item ã' ], >+ [ __xn('one item', '{count} items', 2, count => 2) => '2 items ã' ], >+ [ __xn('one item', '{count} items', 3, count => 3) => '3 items ã' ], >+ [ __p('biblio', 'title') => 'title (biblio) ã' ], >+ [ __p('patron', 'title') => 'title (patron) ã' ], >+ [ __px('biblio', 'Remove item {id}', id => 42) => 'Remove item 42 (biblio) ã' ], >+ [ __px('list', 'Remove item {id}', id => 42) => 'Remove item 42 (list) ã' ], >+ [ __np('ctxt1', 'singular', 'plural', 0) => 'zero (ctxt1) ã' ], >+ [ __np('ctxt1', 'singular', 'plural', 1) => 'singular (ctxt1) ã' ], >+ [ __np('ctxt1', 'singular', 'plural', 2) => 'plural (ctxt1) ã' ], >+ [ __np('ctxt1', 'singular', 'plural', 3) => 'plural (ctxt1) ã' ], >+ [ __np('ctxt2', 'singular', 'plural', 0) => 'zero (ctxt2) ã' ], >+ [ __np('ctxt2', 'singular', 'plural', 1) => 'singular (ctxt2) ã' ], >+ [ __np('ctxt2', 'singular', 'plural', 2) => 'plural (ctxt2) ã' ], >+ [ __np('ctxt2', 'singular', 'plural', 3) => 'plural (ctxt2) ã' ], >+ [ __npx('biblio', 'one item', '{count} items', 0, count => 0) => 'no item (biblio) ã' ], >+ [ __npx('biblio', 'one item', '{count} items', 1, count => 1) => 'one item (biblio) ã' ], >+ [ __npx('biblio', 'one item', '{count} items', 2, count => 2) => '2 items (biblio) ã' ], >+ [ __npx('biblio', 'one item', '{count} items', 3, count => 3) => '3 items (biblio) ã' ], >+ [ __npx('list', 'one item', '{count} items', 0, count => 0) => 'no item (list) ã' ], >+ [ __npx('list', 'one item', '{count} items', 1, count => 1) => 'one item (list) ã' ], >+ [ __npx('list', 'one item', '{count} items', 2, count => 2) => '2 items (list) ã' ], >+ [ __npx('list', 'one item', '{count} items', 3, count => 3) => '3 items (list) ã' ], >+); >+ >+foreach my $test (@tests) { >+ is($test->[0], decode_utf8($test->[1]), $test->[1]); >+} >diff --git a/t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.mo b/t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.mo >new file mode 100644 >index 0000000000000000000000000000000000000000..99be22f268b3e872ac10b2d2e3e538b1fd8293d6 >GIT binary patch >literal 1370 >zcmaKr&rcLF6vwNssG~-O_#;u19ziqf%t9g=SRmpOQC1OGL%f*oZdpoZ+fAoSRta9< >zAMoJKyC=_{{1?1%_u`erf5C63yNm-ulb28XeXp;5oj1RR3!e$bW!N3qF6<g?A7)2z >zijYfS2wnkaz?<N6@GiL4_wRz&vHsNO*FJxMx1sNWH^4uj%{O$KkODXY?m)W*Ud8&$ >z8A2%d4Yc`xf)#Kd90p6+GznJv{0Q3o-@#dM54;DCoOSUt;CZZHf;i@2*m{RxNSofr >z191g%5oX5)hxCrvO3uM-9`c08v7%d&wfQ!AC1k4`GfkG`u4XZ*i+U_nVTHHVCa1#i >zHr*1<?SZbO6UkOXb*0%(Ba(sF2orPCFg+6%l0o8*OKjEB5j7TxIeJ*C9&^+&a)%kM >zWWn9Q@Wha1tu}bW_=`>d4cCcKGNRAaI`dX|M``0%la^@ukGieIuc?T7%P(sFyynax >z(tpehk7y|fANs+B9|km>h=TF^K`96j=&$fiVKbf>x5N_T*EEw!%#6|zecFu$leEgZ >zS~NJF-bmNQwp-7oPhZ!(*ih{mZ;9c<uom}goV6p`>(S|6Z!Q)^rCXWTI^M0Wdey~h >zB`Y&52Hw1qhD%)FeFv2o-ZKw6F%xo%HrAO=xGBG`E%=jJoW1B8*M3DdR1+UBqLX!D >zJl7Zgg3|3IqSAfMq&z-F-LyO^%jJO1(tyHUE{B+gn3l$-yj-i%-#feHE!QfY4Eioz >zxHHn};l`t*t|P}%uT-ujbK;;Q@}ao~&AZYj$x9#Xy++f{btetlHz&G^b5gdk^uLXL >w@!ySo>1d(0>kpNgNm-GZcBsV6F?c5X;s+b;BEQ2b{kL$xk2~G|J?U%z1(g|z>;M1& > >literal 0 >HcmV?d00001 > >diff --git a/t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.po b/t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.po >new file mode 100644 >index 0000000..1b956aa >--- /dev/null >+++ b/t/Koha/I18N/po/xx_XX/LC_MESSAGES/Koha.po >@@ -0,0 +1,81 @@ >+# PO file for tests >+# Copyright (C) 2017 BibLibre >+# This file is distributed under the same license as the Koha package. >+# Julian Maurice <julian.maurice@biblibre.com, 2017. >+# >+#, fuzzy >+msgid "" >+msgstr "" >+"Project-Id-Version: Koha\n" >+"Report-Msgid-Bugs-To: \n" >+"POT-Creation-Date: 2017-04-10 14:03+0200\n" >+"PO-Revision-Date: 2017-04-10 14:03+0200\n" >+"Last-Translator: Julian Maurice <julian.maurice@biblibre.com>\n" >+"Language-Team: xx <xx@li.org>\n" >+"Language: xx_XX\n" >+"MIME-Version: 1.0\n" >+"Content-Type: text/plain; charset=UTF-8\n" >+"Content-Transfer-Encoding: 8bit\n" >+"Plural-Forms: nplurals=3; plural=(n==0 ? 0 : n==1 ? 1 : 2);\n" >+ >+msgid "test" >+msgstr "test ã" >+ >+msgid "Hello {name}" >+msgstr "Hello {name} ã" >+ >+msgid "Singular" >+msgid_plural "Plural" >+msgstr[0] "Zero ã" >+msgstr[1] "Singular ã" >+msgstr[2] "Plural ã" >+ >+msgid "one item" >+msgid_plural "{count} items" >+msgstr[0] "no item ã" >+msgstr[1] "one item ã" >+msgstr[2] "{count} items ã" >+ >+msgctxt "biblio" >+msgid "title" >+msgstr "title (biblio) ã" >+ >+msgctxt "patron" >+msgid "title" >+msgstr "title (patron) ã" >+ >+msgctxt "biblio" >+msgid "Remove item {id}" >+msgstr "Remove item {id} (biblio) ã" >+ >+msgctxt "list" >+msgid "Remove item {id}" >+msgstr "Remove item {id} (list) ã" >+ >+msgctxt "ctxt1" >+msgid "singular" >+msgid_plural "plural" >+msgstr[0] "zero (ctxt1) ã" >+msgstr[1] "singular (ctxt1) ã" >+msgstr[2] "plural (ctxt1) ã" >+ >+msgctxt "ctxt2" >+msgid "singular" >+msgid_plural "plural" >+msgstr[0] "zero (ctxt2) ã" >+msgstr[1] "singular (ctxt2) ã" >+msgstr[2] "plural (ctxt2) ã" >+ >+msgctxt "biblio" >+msgid "one item" >+msgid_plural "{count} items" >+msgstr[0] "no item (biblio) ã" >+msgstr[1] "one item (biblio) ã" >+msgstr[2] "{count} items (biblio) ã" >+ >+msgctxt "list" >+msgid "one item" >+msgid_plural "{count} items" >+msgstr[0] "no item (list) ã" >+msgstr[1] "one item (list) ã" >+msgstr[2] "{count} items (list) ã" >-- >2.1.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 15395
:
45797
|
45798
|
45799
|
46337
|
50023
|
50024
|
50025
|
50026
|
61873
|
61874
|
61875
|
61876
|
61934
|
61935
|
61977
|
62008
|
62041
|
62326
|
62327
|
62328
|
62329
|
62330
|
62331
|
62332
|
62333
|
62335
|
62709
|
65894
|
70974
|
70975
|
70976
|
71940
|
71941
|
71942
|
71943
|
71944
|
71945
|
71946
|
71947
|
71948
|
71949
|
71950
|
71951
|
71952
|
73901
|
73902
|
73903
|
73904
|
73905
|
73906
|
73907
|
73908
|
73909
|
73910
|
73911
|
73912
|
73913
|
76328
|
76329
|
76330
|
77475
|
77476
|
81152
|
81153
|
81154
|
81155
|
81156
|
81157
|
81158
|
81159
|
81167
|
81734
|
81735
|
81736
|
81737
|
81738
|
81739
|
81741
|
81742
|
81743