diff options
author | Jannis M. Hoffmann <jannis.hoffmann@rwth-aachen.de> | 2022-05-07 00:49:24 +0200 |
---|---|---|
committer | Jannis M. Hoffmann <jannis.hoffmann@rwth-aachen.de> | 2022-05-07 00:49:24 +0200 |
commit | 77992072b7963d9a96c11a3913f553c820cc21da (patch) | |
tree | f83db2a926e66d8ab6bdc3527f501cf47a5fb14e | |
parent | 6ac91b3bc730ad8d3476288911e596bbfd2b8880 (diff) |
added localization via Locale::Maketext
-rw-r--r-- | CHANGES.md | 11 | ||||
-rw-r--r-- | Makefile.PL | 4 | ||||
-rw-r--r-- | jwebmail.development.toml | 7 | ||||
-rw-r--r-- | lib/JWebmail/Controller/Webmail.pm | 4 | ||||
-rw-r--r-- | lib/JWebmail/I18N.pm | 16 | ||||
-rw-r--r-- | lib/JWebmail/I18N/de_de.pm | 78 | ||||
-rw-r--r-- | lib/JWebmail/I18N/en_us.pm | 13 | ||||
-rw-r--r-- | lib/JWebmail/Plugin/I18N2.pm | 67 | ||||
-rw-r--r-- | templates/webmail/login.html.ep | 4 |
9 files changed, 181 insertions, 23 deletions
@@ -148,18 +148,13 @@ Current v1.1.0 - [ ] extract version for Makefile.PL from Application - [ ] add basic telemetry (goatcounter?) - [ ] make mime_render return a mojo bytes object +- [ ] advance toml config plugin + - [ ] add template support, maybe + - [ ] add config validation - [x] compute hmac on the client side - [x] better handling on form - [ ] better random numbers -- [ ] advance ini config plugin - - [x] allow non-leaf nodes to be arrays - - [ ] allow quotes - - [ ] allow continuation over multiple lines - - [ ] warn about overrides - - [ ] add template support, maybe - - [x] switch to TOML or a provided format, as INI is too basic - - [ ] add config validation - [ ] improve i18n - [ ] add localization of dates and time - [x] refactor I18N plugin to allow independent translate provider diff --git a/Makefile.PL b/Makefile.PL index 4a9ce64..aad83b0 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -11,10 +11,12 @@ WriteMakefile( Config::Tiny => 'v2.24', Crypt::URandom => 'v0.36', Digest::HMAC_MD5 => '1.04', - Email::MIME => 'v1.951', + Email::MIME => '1.949', Mail::Box::Manager => 'v3.9', Role::Tiny => 'v2.2', Class::Method::Modifiers => 'v2.13', + TOML::Tiny => '0.15', + namespace::clean => '', }, test => {TESTS => 't/*.t'}, ) diff --git a/jwebmail.development.toml b/jwebmail.development.toml index 3975c9f..7f58015 100644 --- a/jwebmail.development.toml +++ b/jwebmail.development.toml @@ -3,11 +3,8 @@ scriptadmin = "me@example.com" # for complaints / support [i18n] default_language = "en" -directory = "lang" - -[i18n.languages] -#en = English -#de = Deutsch +directory = "lib/JWebmail/I18N" +# languages = ["en", "de"] [model.read.driver.devel.json] [model.read.driver.devel.maildir] diff --git a/lib/JWebmail/Controller/Webmail.pm b/lib/JWebmail/Controller/Webmail.pm index bdd7176..c61c493 100644 --- a/lib/JWebmail/Controller/Webmail.pm +++ b/lib/JWebmail/Controller/Webmail.pm @@ -34,7 +34,7 @@ sub auth { my ($pw, $ch) = $self->session_passwd; unless ($user && $pw) { - $self->flash(message => $self->l('no_session')); + $self->flash(message => $self->l('No active session.')); $self->res->code(401); $self->redirect_to('logout'); return 0; @@ -95,7 +95,7 @@ sub login { else { $self->render( status => 401, - warning => $self->l('login') . ' ' . $self->l('failed') . '!', + warning => $self->l('Login failed!'), ); } } diff --git a/lib/JWebmail/I18N.pm b/lib/JWebmail/I18N.pm new file mode 100644 index 0000000..576c413 --- /dev/null +++ b/lib/JWebmail/I18N.pm @@ -0,0 +1,16 @@ +package JWebmail::I18N; + +use parent 'Locale::Maketext'; + + +1 + +__END__ + +=encoding utf-8 + +=head1 NAME + +JWebmail::L10N - Base class for internationalization + +=cut diff --git a/lib/JWebmail/I18N/de_de.pm b/lib/JWebmail/I18N/de_de.pm new file mode 100644 index 0000000..637e88f --- /dev/null +++ b/lib/JWebmail/I18N/de_de.pm @@ -0,0 +1,78 @@ +package JWebmail::I18N::de_de; + +use v5.22; +use warnings; +use utf8; + +use parent 'JWebmail::I18N'; + + +our %Lexicon = ( + 'login' => 'anmelden', + 'userid' => 'nuzerkennung', + 'password' => 'passwort', + 'failed' => 'fehlgeschlagen', + 'about' => 'über', + 'mbox_size' => 'mailboxgröße', + # and = und + 'subject' => 'betreff', + 'version' => 'version', + 'from' => 'von', + 'to' => 'für', + 'cc' => 'cc', + 'date' => 'datum', + 'size' => 'größe', + 'content-type' => 'inhaltsart', + 'send to' => 'senden an', + 'answer_to' => 'antworten gehen an', + 'content' => 'inhalt', + 'check_all' => 'alle markieren', + 'move' => 'verschieben', + 'nr' => 'nummer', + 'status' => 'mehrteilig', + 'logout' => 'abmelden', + 'compose' => 'schreiben', + 'search' => 'suche', + 'of' => 'von', + 'messages' => 'nachrichten', + 'new' => 'neu', + 'mbox_size' => 'mailboxgröße', + 'home' => 'übersicht', + 'no' => 'nein', + 'yes' => 'ja', + 'page' => 'seite', + 'next' => 'nächste', + 'last' => 'letzte', + 'first' => 'erste', + 'previous' => 'vorherige', + 'sender' => 'gesendet von', + 'back' => 'zurück', + + # Mailboxen + 'queue' => 'warteschlange', + 'drafts' => 'vorlagen', + 'home' => 'wurzelverzeichnis', + + # Fehler + 'No active session.' => 'Keine aktive Sitzung.', + 'Login failed!' => 'Einloggen fehlgeschlagen!', + + 'no_folder' => 'Dieses Verzeichnis gibt es nicht.', + 'error_send' => 'Die Nachricht konnte nicht gesendet werden.', + 'succ_send' => 'Die Nachricht wurde verschikt.', + 'succ_move' => 'Nachrichten wurden verschoben.', + 'empty_folder' => 'Dies Verzeichnis ist leer.', +); + + +1 + +__END__ + +=encoding utf-8 + +=head1 NAME + +JWebmail::I18N::de_de - German translation of JWebmail + +=cut diff --git a/lib/JWebmail/I18N/en_us.pm b/lib/JWebmail/I18N/en_us.pm new file mode 100644 index 0000000..22de05e --- /dev/null +++ b/lib/JWebmail/I18N/en_us.pm @@ -0,0 +1,13 @@ +package JWebmail::I18N::en_us; + +use v5.22; +use warnings; +use utf8; + +use parent 'JWebmail::I18N'; + + +our %Lexicon = (_AUTO => 1); + + +1 diff --git a/lib/JWebmail/Plugin/I18N2.pm b/lib/JWebmail/Plugin/I18N2.pm index 9c10c8d..8c57ec5 100644 --- a/lib/JWebmail/Plugin/I18N2.pm +++ b/lib/JWebmail/Plugin/I18N2.pm @@ -2,6 +2,59 @@ package JWebmail::Plugin::I18N2; use Mojo::Base 'Mojolicious::Plugin'; +use List::Util 'any'; + + +package JWebmail::Plugin::I18N2::Maketext { + + use JWebmail::I18N; + use File::Basename 'fileparse'; + + sub new { + my $class = shift; + my $conf = @_ == 1 ? shift : {@_}; + + my $lexica = $conf->{directory} || [fileparse(__FILE__)]->[1] . '../I18N'; + + my @languages = keys %{$conf->{languages} // {}}; + + unless (@languages) { + use autodie; + + opendir(my $dh, $lexica); + my @res = grep { /\.pm$/ && -f "$lexica/$_" } readdir $dh; + closedir($dh); + @languages = map { scalar fileparse $_, '.pm' } @res; + } + + my $self = {}; + for (@languages) { + $self->{$_} = JWebmail::I18N->get_handle($_) || die "unable to load language $_"; + } + + if (my $dl = $conf->{default_language}) { + $self->{$dl} = JWebmail::I18N->get_handle($dl) || die "unable to load language $dl"; + } + + return bless $self, $class; + } + + 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 $phrase = shift; + return $self->{$lang}->maketext($phrase, @_); + } + +} package JWebmail::Plugin::I18N2::Translator { @@ -12,7 +65,6 @@ package JWebmail::Plugin::I18N2::Translator { sub new { my $cls = shift; my $conf = @_ == 1 ? shift : {@_}; - my $self = {}; my @languages = keys %{$conf->{languages} // {}}; @@ -21,6 +73,7 @@ package JWebmail::Plugin::I18N2::Translator { } # load languages + my $self = {}; for my $l (@languages) { if (my $dict = __loadi18n($conf->{directory}, $l)) { $self->{$l} = $dict; @@ -110,11 +163,11 @@ sub register { my $i18n_log = $app->log->context('[' . __PACKAGE__ . ']'); - my $translator = $conf->{translator} || sub { JWebmail::Plugin::I18N2::Translator->new(@_) }; + my $translator = $conf->{translator} || sub { JWebmail::Plugin::I18N2::Maketext->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 $fileLocation = $conf->{directory} + ? Mojo::File->new($conf->{directory}) + : $app->home->child('lang'); my $t = $translator->( default_language => $defaultLang, @@ -126,6 +179,10 @@ sub register { local $" = ','; $i18n_log->info("loaded languages (@{[$t->languages]})"); + unless (any { $defaultLang eq $_ } $t->languages) { + die "default language '$defaultLang' not loaded"; + } + if (keys $conf->{languages}->%* > $t->languages) { $i18n_log->warn("missing languages"); } diff --git a/templates/webmail/login.html.ep b/templates/webmail/login.html.ep index 0b7b080..28768e3 100644 --- a/templates/webmail/login.html.ep +++ b/templates/webmail/login.html.ep @@ -21,14 +21,14 @@ %= text_field 'userid' => '' => (required => '') </div> <div class="pure-control-group"> - %= label_for password => ucfirst l 'passwd' + %= label_for password => ucfirst l 'password' %= password_field 'password' => (required => '') </div> % if ($uses_cram) { %= hidden_field challenge => rand % } <div class="pure-controls"> - %= submit_button l('login') => (class => 'pure-button pure-button-primary') => (name => 'submit_button') => $uses_cram ? (disabled => '') : () + %= submit_button ucfirst l('login') => (class => 'pure-button pure-button-primary') => (name => 'submit_button') => $uses_cram ? (disabled => '') : () </div> </fieldset> % end |