From 1ceb24b1f59dc01bde6ec7d0c31079269ac8b496 Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Sun, 29 Mar 2020 14:56:20 +0200 Subject: [PATCH] Bug 26547: Move context from msgid to msgctxt in pref PO files String extraction for system preferences was putting context inside msgid. For instance: # Accounting > Policy msgid "accounting.pref#FinePaymentAutoPopup# automatically display " "a print dialog for a payment receipt when making a payment.." Now context is put into msgctxt, and the reference is set, which is cleaner #: koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/accounting.pref msgctxt "Accounting > Policy > FinePaymentAutoPopup" msgid "automatically display a print dialog for a payment receipt " "when making a payment.." The downside is that some messages will have to be re-translated, especially short messages like 'Do', for which msgmerge has a hard time finding the corresponding new msgid. Test plan: 1. Run `gulp po:update` 2. Verify the contents of updated pref PO files 3. Run `cd misc/translator && ./translate install ` 4. Verify that sysprefs are correctly translated 5. Run `prove t/misc/translator/xgettext-pref.t` --- misc/translator/LangInstaller.pm | 44 +++++++++++++++++-------------- misc/translator/xgettext-pref | 20 +++++++------- t/misc/translator/xgettext-pref.t | 23 ++++++++++------ 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/misc/translator/LangInstaller.pm b/misc/translator/LangInstaller.pm index 5baddeeccc..be51394452 100644 --- a/misc/translator/LangInstaller.pm +++ b/misc/translator/LangInstaller.pm @@ -148,33 +148,34 @@ sub po_filename { } sub get_trans_text { - my ($self, $msgid, $default) = @_; + my ($self, $msgctxt, $msgid) = @_; - my $po = $self->{po}->{Locale::PO->quote($msgid)}; + my $key = ($msgctxt // '') . ";$msgid"; + + my $po = $self->{po}->{$key}; if ($po) { my $msgstr = Locale::PO->dequote($po->msgstr); - if ($msgstr and length($msgstr) > 0) { - return $msgstr; - } + + return $msgstr || $msgid; } - return $default; + return $msgid; } sub get_translated_tab_content { - my ($self, $file, $tab_content) = @_; + my ($self, $tab, $tab_content) = @_; if ( ref($tab_content) eq 'ARRAY' ) { - return $self->get_translated_prefs($file, $tab_content); + return $self->get_translated_prefs($tab, $tab_content); } my $translated_tab_content = { map { my $section = $_; my $sysprefs = $tab_content->{$section}; - my $msgid = sprintf('%s %s', $file, $section); + my $context = "$tab > $section"; - $self->get_trans_text($msgid, $section) => $self->get_translated_prefs($file, $sysprefs); + $self->get_trans_text($tab, $section) => $self->get_translated_prefs($context, $sysprefs); } keys %$tab_content }; @@ -182,7 +183,7 @@ sub get_translated_tab_content { } sub get_translated_prefs { - my ($self, $file, $sysprefs) = @_; + my ($self, $context, $sysprefs) = @_; my $translated_prefs = [ map { @@ -191,7 +192,7 @@ sub get_translated_prefs { my $translated_syspref = [ map { - $self->get_translated_pref($file, $pref_name, $_); + $self->get_translated_pref("$context > $pref_name", $_ ); } @$_ ]; @@ -203,12 +204,10 @@ sub get_translated_prefs { } sub get_translated_pref { - my ($self, $file, $pref_name, $syspref) = @_; + my ($self, $context, $syspref) = @_; unless (ref($syspref)) { - $syspref //= ''; - my $msgid = sprintf('%s#%s# %s', $file, $pref_name, $syspref); - return $self->get_trans_text($msgid, $syspref); + return $self->get_trans_text($context, $syspref // ''); } my $translated_pref = { @@ -220,8 +219,7 @@ sub get_translated_pref { if (($key eq 'choices' || $key eq 'multiple') && ref($value) eq 'HASH') { $translated_value = { map { - my $msgid = sprintf('%s#%s# %s', $file, $pref_name, $value->{$_}); - $_ => $self->get_trans_text($msgid, $value->{$_}) + $_ => $self->get_trans_text($context, $value->{$_}) } keys %$value } } @@ -241,7 +239,13 @@ sub install_prefs { exit; } - $self->{po} = Locale::PO->load_file_ashash($self->po_filename("-pref.po"), 'utf8'); + my @po_entries = @{ Locale::PO->load_file_asarray($self->po_filename("-pref.po"), 'utf8') }; + $self->{po} = { map { + my $msgctxt = $_->msgctxt ? Locale::PO->dequote($_->msgctxt) : ''; + my $msgid = Locale::PO->dequote($_->msgid); + + "$msgctxt;$msgid" => $_; + } @po_entries }; for my $file ( @{$self->{pref_files}} ) { my $pref = LoadFile( $self->{path_pref_en} . "/$file" ); @@ -251,7 +255,7 @@ sub install_prefs { my $tab = $_; my $tab_content = $pref->{$tab}; - $self->get_trans_text($file, $tab) => $self->get_translated_tab_content($file, $tab_content); + $self->get_trans_text(undef, $tab) => $self->get_translated_tab_content($tab, $tab_content); } keys %$pref }; diff --git a/misc/translator/xgettext-pref b/misc/translator/xgettext-pref index 1113a27f95..7ddbc883fe 100755 --- a/misc/translator/xgettext-pref +++ b/misc/translator/xgettext-pref @@ -45,7 +45,6 @@ display this help and exit use Modern::Perl; -use File::Basename; use Getopt::Long; use Locale::PO; use Pod::Usage; @@ -91,15 +90,14 @@ my $pot = { for my $file (@files) { my $pref = LoadFile($file); while ( my ($tab, $tab_content) = each %$pref ) { - add_po(undef, basename($file)); + add_po($file, undef, $tab); if ( ref($tab_content) eq 'ARRAY' ) { add_prefs( $file, $tab, $tab_content ); } else { while ( my ($section, $sysprefs) = each %$tab_content ) { my $context = "$tab > $section"; - my $msgid = sprintf('%s %s', basename($file), $section); - add_po($tab, $msgid); + add_po($file, $tab, $section); add_prefs( $file, $context, $sysprefs ); } } @@ -125,26 +123,26 @@ sub add_prefs { next unless $key eq 'choices' or $key eq 'multiple'; next unless ref($value) eq 'HASH'; for my $ckey ( keys %$value ) { - my $msgid = sprintf('%s#%s# %s', basename($file), $pref_name, $value->{$ckey}); - add_po( "$context > $pref_name", $msgid ); + add_po( $file, "$context > $pref_name", $value->{$ckey} ); } } } elsif ($element) { - my $msgid = sprintf('%s#%s# %s', basename($file), $pref_name, $element); - add_po( "$context > $pref_name", $msgid ); + add_po( $file, "$context > $pref_name", $element ); } } } } sub add_po { - my ($comment, $msgid ) = @_; + my ( $reference, $msgctxt, $msgid ) = @_; return unless $msgid; - $pot->{$msgid} = Locale::PO->new( - -comment => $comment, + my $key = ($msgctxt // '') . ";$msgid"; + $pot->{$key} = Locale::PO->new( + -reference => $reference, + -msgctxt => $msgctxt, -msgid => $msgid, -msgstr => '', ); diff --git a/t/misc/translator/xgettext-pref.t b/t/misc/translator/xgettext-pref.t index 8c699fe108..4482d67bba 100644 --- a/t/misc/translator/xgettext-pref.t +++ b/t/misc/translator/xgettext-pref.t @@ -20,28 +20,35 @@ my $pot = Locale::PO->load_file_asarray("$tempdir/Koha.pot"); my @expected = ( { - msgid => '"sample.pref"', + msgid => '"Section"', }, { - msgid => '"sample.pref Subsection"', + msgctxt => '"Section > Subsection > MultiplePref"', + msgid => '"Bar"', }, { - msgid => '"sample.pref#MultiplePref# Bar"', + msgctxt => '"Section > Subsection > MultiplePref"', + msgid => '"Baz"', }, { - msgid => '"sample.pref#MultiplePref# Baz"', + msgctxt => '"Section > Subsection > MultiplePref"', + msgid => '"Foo ツ"', }, { - msgid => '"sample.pref#MultiplePref# Foo ツ"', + msgctxt => '"Section > Subsection > SamplePref"', + msgid => '"Do"', }, { - msgid => '"sample.pref#SamplePref# Do"', + msgctxt => '"Section > Subsection > SamplePref"', + msgid => '"Do not do"', }, { - msgid => '"sample.pref#SamplePref# Do not do"', + msgctxt => '"Section > Subsection > SamplePref"', + msgid => '"that thing"', }, { - msgid => '"sample.pref#SamplePref# that thing"', + msgctxt => '"Section"', + msgid => '"Subsection"', }, ); -- 2.20.1