Bug 37303: Replace po2json with a JS version

When using __() (ie. Gettext.js) we are seeing the translations that are marked as fuzzy.
This is definitely not the expected behaviour.

It happens because (our version of) po2json are old and no longer maintained,
and just embed them.

It seems that the bin we have has been upgraded to a JS version
(different authors).

Test plan:
(replace LANG with your language code)
0. Do not apply this patch
Edit misc/translator/po/LANG-messages-js.po
Mark a string as fuzzy
Edit ./intranet-main.tt and add the following lines inside $(document).ready
  console.log(_("Your string"));
  console.log(__("Your string"));
Replace "Your string" with the string you are actually testing.

Update the templates: `koha-translate --update LANG --dev kohadev && restart_all`

Go to the Koha home page, open the console.

=> Notice that the second log in the console is displaying the fuzzy string.

1. Apply this patch
Install the new version of po2json using `yarn install`
Repeat the previous steps.

=> With this patch applied both logs show the English version of the
string.

Remove fuzzy, update the templates and try again.

Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
This commit is contained in:
Jonathan Druart 2024-07-10 12:16:55 +02:00 committed by Martin Renvoize
parent bbd1fa0bfa
commit 4eb9816354
Signed by: martin.renvoize
GPG key ID: 422B469130441A0F
3 changed files with 9 additions and 255 deletions

View file

@ -28,6 +28,7 @@ use Locale::PO;
use FindBin qw( $Bin );
use File::Path qw( make_path );
use File::Copy;
use File::Slurp qw( read_file );
sub set_lang {
my ($self, $lang) = @_;
@ -52,7 +53,7 @@ sub new {
$self->{po} = {};
$self->{domain} = 'Koha';
$self->{msgfmt} = `which msgfmt`;
$self->{po2json} = "$Bin/po2json";
$self->{po2json} = "yarn run po2json";
$self->{gzip} = `which gzip`;
$self->{gunzip} = `which gunzip`;
chomp $self->{msgfmt};
@ -454,7 +455,12 @@ sub install_messages {
make_path($modir);
system "$self->{msgfmt} -o $mofile $pofile";
my $js_locale_data = 'var json_locale_data = {"Koha":' . `$self->{po2json} $js_pofile` . '};';
my $tmp_po = sprintf '/tmp/%s-messages.po', $self->{lang};
my $po2json_cmd = sprintf '%s %s %s', $self->{po2json}, $js_pofile, $tmp_po;
`$po2json_cmd`;
my $json = read_file($tmp_po);
my $js_locale_data = sprintf 'var json_locale_data = {"Koha":%s};', $json;
my $progdir = C4::Context->config('intrahtdocs') . '/prog';
mkdir "$progdir/$self->{lang}/js";
open my $fh, '>', "$progdir/$self->{lang}/js/locale_data.js";

View file

@ -1,253 +0,0 @@
#!/usr/bin/env perl
# PODNAME: po2json
# ABSTRACT: Command line tool for converting a po file into a Gettext.js compatible json dataset
# Copyright (C) 2008, Joshua I. Miller E<lt>unrtst@cpan.orgE<gt>, all
# rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU Library General Public License as published
# by the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
use strict;
use JSON 2.53;
use Locale::PO 0.24;
use File::Basename qw(basename);
my $gettext_context_glue = "\004";
sub usage {
return "$0 {-p} {file.po} > {outputfile.json}
-p : do pretty-printing of json data\n";
}
&main;
sub main
{
my $src;
my $pretty = 0;
if ($ARGV[0] =~ /^--?p$/) {
shift @ARGV;
$pretty = 1;
}
if (length($ARGV[0]))
{
if ($ARGV[0] =~ /^-h/) {
print &usage;
exit 1;
}
unless (-r $ARGV[0]) {
print "ERROR: Unable to read file [$ARGV[0]]\n";
die &usage;
}
$src = $ARGV[0];
} else {
die &usage;
}
# we'll be building this data struct
my $json = {};
my $plural_form_count;
# get po object stack
my $pos = Locale::PO->load_file_asarray($src) or die "Can't parse po file [$src].";
foreach my $po (@$pos)
{
my $qmsgid1 = $po->msgid;
my $msgid1 = $po->dequote( $qmsgid1 );
# on the header
if (length($msgid1) == 0)
{
my $qmsgstr = $po->msgstr;
my $cur = $po->dequote( $qmsgstr );
my %cur;
foreach my $h (split(/\n/, $cur))
{
next unless length($h);
my @h = split(':', $h, 2);
if (length($cur{$h[0]})) {
warn "SKIPPING DUPLICATE HEADER LINE: $h\n";
} elsif ($h[0] =~ /#-#-#-#-#/) {
warn "SKIPPING ERROR MARKER IN HEADER: $h\n";
} elsif (@h == 2) {
$cur{$h[0]} = $h[1];
} else {
warn "PROBLEM LINE IN HEADER: $h\n";
$cur{$h} = '';
}
}
# init header ref
$$json{''} ||= {};
# populate header ref
foreach my $key (keys %cur) {
$$json{''}{$key} = length($cur{$key}) ? $cur{$key} : '';
}
# save plural form count
if ($$json{''}{'Plural-Forms'}) {
my $t = $$json{''}{'Plural-Forms'};
$t =~ s/^\s*//;
if ($t =~ /nplurals=(\d+)/) {
$plural_form_count = $1;
} else {
die "ERROR parsing plural forms header [$t]\n";
}
} else {
warn "NO PLURAL FORM HEADER FOUND - DEFAULTING TO 2\n";
# just default to 2
$plural_form_count = 2;
}
# on a normal msgid
} else {
my $qmsgctxt = $po->msgctxt;
my $msgctxt;
$msgctxt = $po->dequote($qmsgctxt) if $qmsgctxt;
# build the new msgid key
my $msg_ctxt_id = defined($msgctxt) ? join($gettext_context_glue, ($msgctxt, $msgid1)) : $msgid1;
# build translation side
my @trans;
# msgid plural side
my $qmsgid_plural = $po->msgid_plural;
my $msgid2;
$msgid2 = $po->dequote( $qmsgid_plural ) if $qmsgid_plural;
push(@trans, $msgid2);
# translated string
# this shows up different if we're plural
if (defined($msgid2) && length($msgid2))
{
my $plurals = $po->msgstr_n;
for (my $i=0; $i<$plural_form_count; $i++)
{
my $qstr = ref($plurals) ? $$plurals{$i} : undef;
my $str;
$str = $po->dequote( $qstr ) if $qstr;
push(@trans, $str);
}
# singular
} else {
my $qmsgstr = $po->msgstr;
my $msgstr;
$msgstr = $po->dequote( $qmsgstr ) if $qmsgstr;
push(@trans, $msgstr);
}
$$json{$msg_ctxt_id} = \@trans;
}
}
my $jsonobj = JSON->new->canonical( $ENV{CANONICAL} // 1 ); # if you dont want sorted keys, export CANONICAL=0
my $basename = basename($src);
$basename =~ s/\.pot?$//;
if ($pretty)
{
print $jsonobj->pretty->encode( { $basename => $json });
} else {
print $jsonobj->encode($json);
}
}
__END__
=pod
=head1 NAME
po2json - Command line tool for converting a po file into a Gettext.js compatible json dataset
=head1 VERSION
version 0.019
=head1 SYNOPSIS
po2json /path/to/domain.po > domain.json
=head1 DESCRIPTION
This takes a PO file, as is created from GNU Gettext's xgettext, and converts it into a JSON file.
The output is an annonymous associative array. So, if you plan to load this via a <script> tag, more processing will be require (the output from this program must be assigned to a named javascript variable). For example:
echo -n "var json_locale_data = " > domain.json
po2json /path/to/domain.po >> domain.json
echo ";" >> domain.json
=head1 NAME
po2json - Convert a Uniforum format portable object file to javascript object notation.
=head1 OPTIONS
-p : pretty-print the output. Makes the output more human-readable.
=head1 BUGS
Locale::PO has a potential bug (I don't know if this actually causes a problem or not). Given a .po file with an entry like:
msgid ""
"some string"
msgstr ""
When $po->dump is run on that entry, it will output:
msgid "some string"
msgstr ""
The above is removing the first linebreak. I don't know if that is significant. If so, we'll have to rewrite using a different parser (or include our own parser).
=head1 REQUIRES
Locale::PO
JSON
=head1 SEE ALSO
Locale::PO
Gettext.js
=head1 AUTHOR
Copyright (C) 2008, Joshua I. Miller E<lt>unrtst@cpan.orgE<gt>, all rights reserved. See the source code for details.
=head1 AUTHOR
Torsten Raudssus <torsten@raudss.us>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by DuckDuckGo, Inc. L<http://duckduckgo.com/>, Torsten Raudssus <torsten@raudss.us>.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut

View file

@ -36,6 +36,7 @@
"minimist": "^1.2.5",
"mysql": "^2.18.1",
"pinia": "^2.0.13",
"po2json": "^0.4.5",
"sass": "^1.58.1",
"style-loader": "^3.3.1",
"vue": "^3.2.31",