]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - IkiWiki/Plugin/po.pm
comment
[git.ikiwiki.info.git] / IkiWiki / Plugin / po.pm
index 2244126761a8323a7269786724558ffe56c350b4..6395ebdc2f99f91e3316b89cb017d157e895f81b 100644 (file)
@@ -28,6 +28,7 @@ use UNIVERSAL;
 my %translations;
 my @origneedsbuild;
 my %origsubs;
 my %translations;
 my @origneedsbuild;
 my %origsubs;
+my @slavelanguages; # language codes ordered as in config po_slave_languages
 
 memoize("istranslatable");
 memoize("_istranslation");
 
 memoize("istranslatable");
 memoize("_istranslation");
@@ -104,11 +105,11 @@ sub getsetup () {
                },
                po_slave_languages => {
                        type => "string",
                },
                po_slave_languages => {
                        type => "string",
-                       example => {
-                               'fr' => 'Français',
-                               'es' => 'Español',
-                               'de' => 'Deutsch'
-                       },
+                       example => [
+                               'fr|Français',
+                               'es|Español',
+                               'de|Deutsch'
+                       ],
                        description => "slave languages (PO files)",
                        safe => 1,
                        rebuild => 1,
                        description => "slave languages (PO files)",
                        safe => 1,
                        rebuild => 1,
@@ -137,12 +138,33 @@ sub checkconfig () {
                                      $field, 'po'));
                }
        }
                                      $field, 'po'));
                }
        }
+
+       if (ref $config{po_slave_languages} eq 'ARRAY') {
+               my %slaves;
+               foreach my $pair (@{$config{po_slave_languages}}) {
+                       my ($code, $name) = ( $pair =~ /^([a-z]{2})\|(.+)$/ );
+                       if (!defined $code || !defined $name) {
+                               error(sprintf(gettext("%s has invalid syntax: must use CODE|NAME"),
+                                             $pair));
+                       }
+                       $slaves{$code} = $name;
+                       push @slavelanguages, $code;
+
+               }
+               $config{po_slave_languages} = \%slaves;
+       }
+       elsif (ref $config{po_slave_languages} eq 'HASH') {
+               @slavelanguages = sort {
+                       $config{po_slave_languages}->{$a} cmp $config{po_slave_languages}->{$b};
+               } keys %{$config{po_slave_languages}};
+       }
+
        delete $config{po_slave_languages}{$config{po_master_language}{code}};;
 
        map {
                islanguagecode($_)
                        or error(sprintf(gettext("%s is not a valid language code"), $_));
        delete $config{po_slave_languages}{$config{po_master_language}{code}};;
 
        map {
                islanguagecode($_)
                        or error(sprintf(gettext("%s is not a valid language code"), $_));
-       } ($config{po_master_language}{code}, keys %{$config{po_slave_languages}});
+       } ($config{po_master_language}{code}, @slavelanguages);
 
        if (! exists $config{po_translatable_pages} ||
            ! defined $config{po_translatable_pages}) {
 
        if (! exists $config{po_translatable_pages} ||
            ! defined $config{po_translatable_pages}) {
@@ -171,7 +193,7 @@ sub checkconfig () {
                next if $underlay=~/^locale\//;
 
                # Underlays containing the po files for slave languages.
                next if $underlay=~/^locale\//;
 
                # Underlays containing the po files for slave languages.
-               foreach my $ll (keys %{$config{po_slave_languages}}) {
+               foreach my $ll (@slavelanguages) {
                        add_underlay("po/$ll/$underlay")
                                if -d "$config{underlaydirbase}/po/$ll/$underlay";
                }
                        add_underlay("po/$ll/$underlay")
                                if -d "$config{underlaydirbase}/po/$ll/$underlay";
                }
@@ -197,7 +219,7 @@ sub needsbuild () {
 
        # make existing translations depend on the corresponding master page
        foreach my $master (keys %translations) {
 
        # make existing translations depend on the corresponding master page
        foreach my $master (keys %translations) {
-               map add_depends($_, $master), values %{otherlanguages($master)};
+               map add_depends($_, $master), values %{otherlanguages_pages($master)};
        }
 }
 
        }
 }
 
@@ -229,7 +251,7 @@ sub scan (@) {
                                # make sure any destpage's translations has
                                # $page in its backlinks
                                push @{$links{$page}},
                                # make sure any destpage's translations has
                                # $page in its backlinks
                                push @{$links{$page}},
-                                       values %{otherlanguages($destpage)};
+                                       values %{otherlanguages_pages($destpage)};
                        }
                }
        }
                        }
                }
        }
@@ -287,7 +309,7 @@ sub pagetemplate (@) {
        }
        if ($template->query(name => "otherlanguages")) {
                $template->param(otherlanguages => [otherlanguagesloop($page)]);
        }
        if ($template->query(name => "otherlanguages")) {
                $template->param(otherlanguages => [otherlanguagesloop($page)]);
-               map add_depends($page, $_), (values %{otherlanguages($page)});
+               map add_depends($page, $_), (values %{otherlanguages_pages($page)});
        }
        if ($config{discussion} && istranslation($page)) {
                if ($page !~ /.*\/\Q$config{discussionpage}\E$/i &&
        }
        if ($config{discussion} && istranslation($page)) {
                if ($page !~ /.*\/\Q$config{discussionpage}\E$/i &&
@@ -340,12 +362,12 @@ sub renamepages (@) {
        return () unless istranslatable($torename{src});
 
        my @ret;
        return () unless istranslatable($torename{src});
 
        my @ret;
-       my %otherpages=%{otherlanguages($torename{src})};
+       my %otherpages=%{otherlanguages_pages($torename{src})};
        while (my ($lang, $otherpage) = each %otherpages) {
                push @ret, {
                        src => $otherpage,
                        srcfile => $pagesources{$otherpage},
        while (my ($lang, $otherpage) = each %otherpages) {
                push @ret, {
                        src => $otherpage,
                        srcfile => $pagesources{$otherpage},
-                       dest => otherlanguage($torename{dest}, $lang),
+                       dest => otherlanguage_page($torename{dest}, $lang),
                        destfile => $torename{dest}.".".$lang.".po",
                        required => 0,
                };
                        destfile => $torename{dest}.".".$lang.".po",
                        required => 0,
                };
@@ -536,7 +558,7 @@ sub formbuilder (@) {
        # This cannot be done in the formbuilder_setup hook as the list of types is
        # computed later.
        if ($form->field("do") eq "create") {
        # This cannot be done in the formbuilder_setup hook as the list of types is
        # computed later.
        if ($form->field("do") eq "create") {
-               foreach my $field ($form->field) {
+               foreach my $field ($form->field) {
                        next unless "$field" eq "type";
                        next unless $field->type eq 'select';
                        my $orig_value = $field->value;
                        next unless "$field" eq "type";
                        next unless $field->type eq 'select';
                        my $orig_value = $field->value;
@@ -593,7 +615,7 @@ sub mybeautify_urlpath ($) {
                $res =~ s!/\Qindex.$config{htmlext}\E$!/!;
                map {
                        $res =~ s!/\Qindex.$_.$config{htmlext}\E$!/!;
                $res =~ s!/\Qindex.$config{htmlext}\E$!/!;
                map {
                        $res =~ s!/\Qindex.$_.$config{htmlext}\E$!/!;
-               } (keys %{$config{po_slave_languages}});
+               } @slavelanguages;
        }
        return $res;
 }
        }
        return $res;
 }
@@ -684,7 +706,7 @@ sub myisselflink ($$) {
        return 1 if $origsubs{'isselflink'}->($page, $link);
        if (istranslation($page)) {
                return $origsubs{'isselflink'}->(masterpage($page), $link);
        return 1 if $origsubs{'isselflink'}->($page, $link);
        if (istranslation($page)) {
                return $origsubs{'isselflink'}->(masterpage($page), $link);
-        }
+       }
        return;
 }
 
        return;
 }
 
@@ -812,7 +834,7 @@ sub islanguagecode ($) {
        return $code =~ /^[a-z]{2}$/;
 }
 
        return $code =~ /^[a-z]{2}$/;
 }
 
-sub otherlanguage ($$) {
+sub otherlanguage_page ($$) {
        my $page=shift;
        my $code=shift;
 
        my $page=shift;
        my $code=shift;
 
@@ -820,17 +842,31 @@ sub otherlanguage ($$) {
        return masterpage($page) . '.' . $code;
 }
 
        return masterpage($page) . '.' . $code;
 }
 
-sub otherlanguages ($) {
+# Returns the list of other languages codes: the master language comes first,
+# then the codes are ordered the same way as in po_slave_languages, if it is
+# an array, or in the language name lexical order, if it is a hash.
+sub otherlanguages_codes ($) {
        my $page=shift;
 
        my $page=shift;
 
-       my %ret;
-       return \%ret unless istranslation($page) || istranslatable($page);
+       my @ret;
+       return \@ret unless istranslation($page) || istranslatable($page);
        my $curlang=lang($page);
        foreach my $lang
        my $curlang=lang($page);
        foreach my $lang
-               ($config{po_master_language}{code}, keys %{$config{po_slave_languages}}) {
+               ($config{po_master_language}{code}, @slavelanguages) {
                next if $lang eq $curlang;
                next if $lang eq $curlang;
-               $ret{$lang}=otherlanguage($page, $lang);
+               push @ret, $lang;
        }
        }
+       return \@ret;
+}
+
+sub otherlanguages_pages ($) {
+       my $page=shift;
+
+       my %ret;
+       map {
+               $ret{$_} = otherlanguage_page($page, $_)
+       } @{otherlanguages_codes($page)};
+
        return \%ret;
 }
 
        return \%ret;
 }
 
@@ -854,7 +890,7 @@ sub pofile ($$) {
 sub pofiles ($) {
        my $masterfile=shift;
 
 sub pofiles ($) {
        my $masterfile=shift;
 
-       return map pofile($masterfile, $_), (keys %{$config{po_slave_languages}});
+       return map pofile($masterfile, $_), @slavelanguages;
 }
 
 sub refreshpot ($) {
 }
 
 sub refreshpot ($) {
@@ -981,30 +1017,25 @@ sub otherlanguagesloop ($) {
        my $page=shift;
 
        my @ret;
        my $page=shift;
 
        my @ret;
-       my %otherpages=%{otherlanguages($page)};
-       while (my ($lang, $otherpage) = each %otherpages) {
-               if (istranslation($page) && masterpage($page) eq $otherpage) {
-                       push @ret, {
-                               url => urlto_with_orig_beautiful_urlpath($otherpage, $page),
-                               code => $lang,
-                               language => languagename($lang),
-                               master => 1,
-                       };
-               }
-               elsif (istranslation($otherpage)) {
-                       push @ret, {
-                               url => urlto_with_orig_beautiful_urlpath($otherpage, $page),
-                               code => $lang,
-                               language => languagename($lang),
-                               percent => percenttranslated($otherpage),
-                       }
+       if (istranslation($page)) {
+               push @ret, {
+                       url => urlto_with_orig_beautiful_urlpath(masterpage($page), $page),
+                       code => $config{po_master_language}{code},
+                       language => $config{po_master_language}{name},
+                       master => 1,
+               };
+       }
+       foreach my $lang (@{otherlanguages_codes($page)}) {
+               next if $lang eq $config{po_master_language}{code};
+               my $otherpage = otherlanguage_page($page, $lang);
+               push @ret, {
+                       url => urlto_with_orig_beautiful_urlpath($otherpage, $page),
+                       code => $lang,
+                       language => languagename($lang),
+                       percent => percenttranslated($otherpage),
                }
        }
                }
        }
-       return sort {
-               return -1 if $a->{code} eq $config{po_master_language}{code};
-               return 1 if $b->{code} eq $config{po_master_language}{code};
-               return $a->{language} cmp $b->{language};
-       } @ret;
+       return @ret;
 }
 
 sub homepageurl (;$) {
 }
 
 sub homepageurl (;$) {
@@ -1017,7 +1048,7 @@ sub ishomepage ($) {
        my $page = shift;
 
        return 1 if $page eq 'index';
        my $page = shift;
 
        return 1 if $page eq 'index';
-       map { return 1 if $page eq 'index.'.$_ } keys %{$config{po_slave_languages}};
+       map { return 1 if $page eq 'index.'.$_ } @slavelanguages;
        return undef;
 }
 
        return undef;
 }
 
@@ -1032,7 +1063,7 @@ sub deletetranslations ($) {
                if (-e $absfile && ! -l $absfile && ! -d $absfile) {
                        push @todelete, $file;
                }
                if (-e $absfile && ! -l $absfile && ! -d $absfile) {
                        push @todelete, $file;
                }
-       } keys %{$config{po_slave_languages}};
+       } @slavelanguages;
 
        map {
                if ($config{rcs}) {
 
        map {
                if ($config{rcs}) {
@@ -1163,7 +1194,7 @@ sub isvalidpo ($) {
        unlink $infile;
 
        if ($res) {
        unlink $infile;
 
        if ($res) {
-           return IkiWiki::SuccessReason->new("valid gettext data");
+               return IkiWiki::SuccessReason->new("valid gettext data");
        }
        return IkiWiki::FailReason->new(gettext("invalid gettext data, go back ".
                                        "to previous page to continue edit"));
        }
        return IkiWiki::FailReason->new(gettext("invalid gettext data, go back ".
                                        "to previous page to continue edit"));
@@ -1175,7 +1206,7 @@ sub po4a_type ($) {
        my $pagetype = pagetype($file);
        if ($pagetype eq 'html') {
                return 'xhtml';
        my $pagetype = pagetype($file);
        if ($pagetype eq 'html') {
                return 'xhtml';
-        }
+       }
        return 'text';
 }
 
        return 'text';
 }
 
@@ -1189,13 +1220,13 @@ sub po4a_options($) {
                # how to disable options is not consistent across po4a modules
                $options{includessi} = '';
                $options{includeexternal} = 0;
                # how to disable options is not consistent across po4a modules
                $options{includessi} = '';
                $options{includeexternal} = 0;
-        }
+       }
        elsif ($pagetype eq 'mdwn') {
                $options{markdown} = 1;
        elsif ($pagetype eq 'mdwn') {
                $options{markdown} = 1;
-        }
-        else {
+       }
+       else {
                $options{markdown} = 0;
                $options{markdown} = 0;
-        }
+       }
 
        return %options;
 }
 
        return %options;
 }
@@ -1270,11 +1301,11 @@ sub match_needstranslation ($$;@) {
                }
                elsif ($wanted > 100) {
                        return IkiWiki::FailReason->new("parameter is greater than 100");
                }
                elsif ($wanted > 100) {
                        return IkiWiki::FailReason->new("parameter is greater than 100");
-                }
-        }
-        else {
+               }
+       }
+       else {
                $wanted=100;
                $wanted=100;
-        }
+       }
 
        my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page);
        if ($percenttranslated eq 'N/A') {
 
        my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page);
        if ($percenttranslated eq 'N/A') {
@@ -1282,7 +1313,7 @@ sub match_needstranslation ($$;@) {
        }
        elsif ($percenttranslated < $wanted) {
                return IkiWiki::SuccessReason->new("file has $percenttranslated translated");
        }
        elsif ($percenttranslated < $wanted) {
                return IkiWiki::SuccessReason->new("file has $percenttranslated translated");
-        }
+       }
        else {
                return IkiWiki::FailReason->new("file is translated enough");
        }
        else {
                return IkiWiki::FailReason->new("file is translated enough");
        }