Skip to content

Instantly share code, notes, and snippets.

@norbornen
Last active January 31, 2020 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save norbornen/926487835deaaf3bd6aacc27d7c46797 to your computer and use it in GitHub Desktop.
Save norbornen/926487835deaaf3bd6aacc27d7c46797 to your computer and use it in GitHub Desktop.
Perl Template Toolkit multilang and pluralisation plugin
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