diff options
author | Jannis M. Hoffmann <jannis.hoffmann@rwth-aachen.de> | 2022-04-22 19:31:45 +0200 |
---|---|---|
committer | Jannis M. Hoffmann <jannis.hoffmann@rwth-aachen.de> | 2022-04-22 19:31:45 +0200 |
commit | 5c3fa491eebc690fbac8a963996a0244882813c7 (patch) | |
tree | 784623eb6b652ff98473549c48c7a997898fc38e /lib/JWebmail/Plugin/I18N2.pm | |
parent | e1bafc13858b5c72a7584c52d3d9d6d597d39e6b (diff) |
refactored plugin I18N2
added actions script
Diffstat (limited to 'lib/JWebmail/Plugin/I18N2.pm')
-rw-r--r-- | lib/JWebmail/Plugin/I18N2.pm | 230 |
1 files changed, 132 insertions, 98 deletions
diff --git a/lib/JWebmail/Plugin/I18N2.pm b/lib/JWebmail/Plugin/I18N2.pm index 5084c97..35367e9 100644 --- a/lib/JWebmail/Plugin/I18N2.pm +++ b/lib/JWebmail/Plugin/I18N2.pm @@ -2,11 +2,65 @@ package JWebmail::Plugin::I18N2; use Mojo::Base 'Mojolicious::Plugin'; -use Mojolicious::Controller; -use Mojo::File; -use Mojo::Util 'monkey_patch'; -use Config::Tiny; +package JWebmail::Plugin::I18N2::Translator { + + use Mojo::File; + + use Config::Tiny; + + sub new { + my $cls = shift; + my $conf = @_ == 1 ? shift : {@_}; + my $self = {}; + + my @languages = keys %{$conf->{languages} // {}}; + + unless (@languages) { + @languages = map { s|^.*/(..)\.lang$|$1|r } glob("'$conf->{directory}/*.lang'"); + } + + # load languages + for my $l (@languages) { + if (my $dict = __loadi18n($conf->{directory}, $l)) { + $self->{$l} = $dict; + } + } + + return bless $self, $cls; + } + + sub languages { + my $self = shift; + if (@_) { + return exists $self->{$_[0]}; + } + return wantarray ? sort keys $self->%* : scalar keys $self->%*; + } + + sub translate { + my $self = shift; + my $lang = shift; + my $word = shift; + return $self->{$lang}{$word}; + } + + sub __loadi18n { + my $langsubdir = shift; + my $lang = shift; + + my $langFile = "$langsubdir/$lang.lang"; + my $TXT; + + if ( -f $langFile ) { + $TXT = Config::Tiny->read($langFile, 'utf8')->{'_'}; + if ($@) { + die "error reading file $langFile: $@"; + } + } + return $TXT; + } +} package JWebmail::Plugin::I18N2::Match { @@ -14,83 +68,85 @@ package JWebmail::Plugin::I18N2::Match { has '_i18n2_stash'; + sub __add_option_no_override { + my $key = shift; + my $value = shift; + + if (ref $_[0] eq 'HASH' && @_ == 1) { + $_[0]->{$key} ||= $value; + } + elsif (ref $_[1] eq 'HASH' && @_ == 2) { + $_[1]->{$key} ||= $value; + } + else { + my ($dom, %args) = @_%2 == 0 ? (undef, @_) : @_; + $args{$key} ||= $value; + @_ = ($dom, %args); + shift @_ unless defined $_[0]; + } + return @_; + } + sub path_for { my $self = shift; + my @args = @_; if (my $lang = $self->_i18n2_stash->{lang}) { - if (ref $_[0] eq 'HASH') { - $_[0]->{lang} ||= $lang; - } - elsif (ref $_[1] eq 'HASH') { - $_[1]->{lang} ||= $lang; - } - else { - my ($dom, %args) = @_%2 == 0 ? (undef, @_) : @_; - $args{lang} ||= $lang; - @_ = ($dom, %args); - shift @_ unless defined $_[0]; - } + @args = __add_option_no_override(lang => $lang, @args); } - $self->next::method(@_) + return $self->SUPER::path_for(@args); } } -has '_language_loaded' => sub { {} }; - - sub register { my ($self, $app, $conf) = @_; $conf //= {}; my $i18n_log = $app->log->context('[' . __PACKAGE__ . ']'); - # config - # 1. what languages - # 2. where are the files - # 3. fallback language - # - # look for languages automatically + my $translator = $conf->{translator} || sub { JWebmail::Plugin::I18N2::Translator->new(@_) }; my $defaultLang = $conf->{default_language} || 'en'; my $fileLocation = $conf->{directory} && Mojo::File->new($conf->{directory})->is_abs - ? $conf->{directory} - : $app->home->child($conf->{directory} || 'lang'); - my @languages = keys %{$conf->{languages} // {}}; + ? $conf->{directory} + : $app->home->child($conf->{directory} || 'lang'); - unless (@languages) { - @languages = map { $_ =~ s|^.*/(..)\.lang$|$1|r } glob("$fileLocation/*.lang"); - } - - $app->defaults(languages => [@languages]); - - # load languages - my $TXT; - for my $l (@languages) { - $TXT->{$l} = _loadi18n($fileLocation, $l, $i18n_log); - } + my $t = $translator->( + default_language => $defaultLang, + directory => $fileLocation, + %{$conf->{rest} // {}} + ); { local $" = ','; - $i18n_log->debug("loaded languages (@languages)"); + $i18n_log->debug("loaded languages (@{[$t->languages]})"); + + if (keys $conf->{languages}->%* > $t->languages) { + $i18n_log->warn("missing languages"); + } } - $self->_language_loaded( { map { $_ => 1 } @languages } ); + $app->defaults(default_language => $defaultLang); + $app->defaults(languages => [$t->languages]); # add translator as helper - my $i18n = sub { - my ($lang, $word) = @_; - $TXT->{$lang}{$word} || scalar( - local $" = ' ', - $lang && $word ? $app->log->debug('[' . __PACKAGE__ . "] missing translation for $lang:$word @{[ caller(2) ]}[0..2]") : (), - '', - ) - }; - $app->helper( l => sub { my $c = shift; $i18n->($c->stash->{lang}, shift) } ); + $app->helper(l => sub { + my $c = shift; + my $lang = @_ == 2 ? $_[0] : $c->stash->{lang}; + my $word = @_ == 2 ? $_[1] : $_[0]; + + my $res = $t->translate($lang, $word); + unless ($res) { + local $" = ' '; + $app->log->warn('[' . __PACKAGE__ . "] missing translation for '$lang':'$word' @{[ caller(1) ]}[0..2]"); + } + return $res; + }); # modify incoming url $app->hook(before_dispatch => sub { my $c = shift; unshift @{ $c->req->url->path->parts }, '' - unless $self->_language_loaded->{$c->req->url->path->parts->[0] || ''}; + unless $t->languages($c->req->url->path->parts->[0] || ''); }); # modify generated url @@ -105,29 +161,6 @@ sub register { return $app->routes->any('/:lang' => {lang => $defaultLang}); } - -sub _loadi18n { - - my $langsubdir = shift; - my $lang = shift; - my $log = shift; - - my $langFile = "$langsubdir/$lang.lang"; - my $TXT; - - if ( -f $langFile ) { - $TXT = Config::Tiny->read($langFile, 'utf8')->{'_'}; - if ($@ || !defined $TXT) { - $log->error("error reading file $langFile: $@"); - } - } - else { - $log->warn("language file $langFile does not exist!"); - } - return $TXT; -} - - 1 __END__ @@ -140,32 +173,32 @@ JWebmail::Plugin::I18N2 - Custom Made I18N Support an alternative to JWebmail::P =head1 SYNOPSIS - $app->plugin('I18N2', { - languages => [qw(en de es)], - default_language => 'en', - directory => '/path/to/language/files/', - }) + $app->plugin('I18N2', { + languages => [qw(en de es)], + default_language => 'de', + directory => 'path/to/language/files/', + }) - # in your controller - $c->l('hello') + # in your controller + $c->l('hello') - # in your templates - <%= l 'hello' %> + # in your templates + <%= l 'hello' %> - @@ de.lang - login = anmelden - userid = nuzerkennung - passwd = passwort - failed = fehlgeschlagen - about = über + @@ de.lang + login = anmelden + userid = nuzerkennung + passwd = passwort + failed = fehlgeschlagen + about = über - example.com/de/myroute # $c->stash('lang') eq 'de' - example.com/myroute # $c->stash('lang') eq $defaultLanguage + example.com/de/myroute # $c->stash('lang') eq 'de' + example.com/myroute # $c->stash('lang') eq $defaultLanguage - # on example.com/de/myroute - url_for('my_other_route') #=> example.com/de/my_other_route + # on example.com/de/myroute + url_for('my_other_route') #=> example.com/de/my_other_route - url_for('my_other_route', lang => 'es') #=> example.com/es/my_other_route + url_for('my_other_route', lang => 'es') #=> example.com/es/my_other_route =head1 DESCRIPTION @@ -177,6 +210,8 @@ Be carefult with colliding routes. Mojolicious::Controller::url_for is patched so that the current language will be kept for router named urls. +This Plugin only works with Mojolicious version 8.64 or higher. + =head1 OPTIONS =head2 default_language @@ -190,7 +225,7 @@ Directory to look for language files. =head2 languages List of allowed languages. -Files of the pattern "$lang.lang" will be looked for. +As a default, files of the pattern "$lang.lang" will be looked for. =head1 HELPERS @@ -198,7 +233,6 @@ Files of the pattern "$lang.lang" will be looked for. This is used for your translations. - $c->l('hello') - $app->helper('hello')->() + $c->l('hello') =cut |