summaryrefslogtreecommitdiff
path: root/lib/JWebmail/Plugin
diff options
context:
space:
mode:
Diffstat (limited to 'lib/JWebmail/Plugin')
-rw-r--r--lib/JWebmail/Plugin/I18N2.pm230
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