From 2ed5cbf408f6e1b5941870de13e3859588a15b2b 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` Signed-off-by: Martin Renvoize --- misc/translator/LangInstaller.pm | 50 ++++++++++--------- misc/translator/xgettext-pref | 20 ++++---- .../misc/translator/xgettext-pref.t | 23 ++++++--- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/misc/translator/LangInstaller.pm b/misc/translator/LangInstaller.pm index 8f3cf59df4b..c22bac6690b 100644 --- a/misc/translator/LangInstaller.pm +++ b/misc/translator/LangInstaller.pm @@ -150,33 +150,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 and not defined( $po->fuzzy() ) ) { 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 }; @@ -197,14 +198,14 @@ sub get_translated_tab_content { } sub get_translated_prefs { - my ( $self, $file, $sysprefs ) = @_; + my ( $self, $context, $sysprefs ) = @_; my $translated_prefs = [ map { my ($pref_elt) = grep { ref($_) eq 'HASH' && exists $_->{pref} } @$_; my $pref_name = $pref_elt ? $pref_elt->{pref} : ''; - my $translated_syspref = [ map { $self->get_translated_pref( $file, $pref_name, $_ ); } @$_ ]; + my $translated_syspref = [ map { $self->get_translated_pref( "$context > $pref_name", $_ ); } @$_ ]; $translated_syspref; } @$sysprefs @@ -214,12 +215,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 = { @@ -229,12 +228,7 @@ sub get_translated_pref { my $translated_value = $value; if ( ( $key eq 'choices' || $key eq 'multiple' || $key eq 'multiple_sortable' ) && ref($value) eq 'HASH' ) { - $translated_value = { - map { - my $msgid = sprintf( '%s#%s# %s', $file, $pref_name, $value->{$_} ); - $_ => $self->get_trans_text( $msgid, $value->{$_} ) - } keys %$value - }; + $translated_value = { map { $_ => $self->get_trans_text( $context, $value->{$_} ) } keys %$value }; } $key => $translated_value @@ -252,7 +246,15 @@ 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 = YAML::XS::LoadFile( $self->{path_pref_en} . "/$file" ); @@ -262,7 +264,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 3134d42633f..50eb47ef5c3 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; @@ -89,15 +88,14 @@ my $pot = { for my $file (@files) { my $pref = YAML::XS::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 ); } } @@ -123,26 +121,26 @@ sub add_prefs { next unless $key eq 'choices' or $key eq 'multiple' or $key eq 'multiple_sortable'; 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/db_dependent/misc/translator/xgettext-pref.t b/t/db_dependent/misc/translator/xgettext-pref.t index 48ad8856112..3c29c9d6c02 100755 --- a/t/db_dependent/misc/translator/xgettext-pref.t +++ b/t/db_dependent/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.47.3