Last active
January 31, 2020 15:14
-
-
Save norbornen/926487835deaaf3bd6aacc27d7c46797 to your computer and use it in GitHub Desktop.
Perl Template Toolkit multilang and pluralisation plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Example::TT2::M; | |
use strict; | |
use warnings; | |
use base 'Template::Plugin'; | |
use Locale::CLDR; | |
use Scalar::Util qw/looks_like_number/; | |
sub new { | |
my ($class, $context, $lang) = @_; | |
$lang ||= 'ru'; | |
my $persistent_langs = [ $lang ]; | |
if ($lang ne 'ru') { | |
push @$persistent_langs, 'en', 'ru'; | |
} | |
push @$persistent_langs, '*'; | |
bless { | |
_CONTEXT => $context, | |
__lang => $lang || 'ru', | |
__persistent_langs => $persistent_langs | |
}, $class; | |
} | |
# | |
# [% M.lv(data.season.name) %] | |
# | |
sub lv { | |
my ($self, $vars) = @_; | |
my $r = exists $vars->{$self->{__lang}} ? $vars->{$self->{__lang}} : 'EMPTY_LANG_VARIANT'; | |
return $r; | |
} | |
# | |
# [% M.persistent_lv(data.season.name) %] | |
# | |
sub persistent_lv { | |
my ($self, $vars) = @_; | |
if (not ref $vars or not defined $self->{__persistent_langs}) { | |
return $vars; | |
} | |
my $val; | |
foreach my $l (@{ $self->{__persistent_langs} }) { | |
if (exists $vars->{$l} and defined $vars->{$l}) { | |
$val = $vars->{$l}; | |
last; | |
} | |
} | |
return $val; | |
} | |
# | |
# [% ticketsCount _ ' ' _ M.plurality(ticketsCount, 'билет|билета|билетов') %] | |
# | |
sub plurality { | |
my ($self, $n, $fr) = @_; | |
return _plurality($self->{__lang}, $n, $fr); | |
} | |
# | |
# [% ticketsCount _ ' ' _ M.plurality_lv(ticketsCount, {ru=>'билет|билета|билетов', en=>'ticket|tickets'}) %] | |
# | |
sub plurality_lv { | |
my ($self, $n, $fr_lv) = @_; | |
if (defined $fr_lv) { | |
if (ref $fr_lv ne 'HASH') { | |
return _plurality($self->{__lang}, $n, $fr_lv); | |
} elsif (defined $self->{__persistent_langs}) { | |
foreach my $l (@{ $self->{__persistent_langs} }) { | |
if (exists $fr_lv->{$l} and defined $fr_lv->{$l}) { | |
return _plurality($l, $n, $fr_lv->{$l}); | |
} | |
} | |
} | |
} | |
return $fr_lv || 'EMPTY_LANG_VARIANTS'; | |
} | |
sub _plurality { | |
my ($lang, $n, $fr) = @_; | |
my $val; | |
my @fragments_array = ref $fr eq 'ARRAY' ? @$fr : split(/\|/, $fr); # one|few|many or one|many | |
if (not defined $n or not looks_like_number($n)) { | |
$val = 'NOT_LOOKS_LIKE_NUMBER'; | |
} elsif(not @fragments_array) { | |
$val = 'NOT_HAVE_FRAGMENTS'; | |
} else { | |
my %fragments = (); | |
$fragments{one} = shift @fragments_array; | |
$fragments{many} = pop @fragments_array; | |
$fragments{few} = @fragments_array ? $fragments_array[0] : $fragments{many}; | |
my $locale = Locale::CLDR->new(language_id => $lang); | |
my $plural_rule = $locale->plural($n); | |
$val = exists $fragments{ $plural_rule } ? $fragments{ $plural_rule } : $fragments{ 'many' }; | |
} | |
return $val; | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment