use File::Spec;
use File::Temp;
use Memoize;
-use UNIVERSAL;
my ($master_language_code, $master_language_name);
my %translations;
my @origneedsbuild;
my %origsubs;
my @slavelanguages; # language codes ordered as in config po_slave_languages
+my %slavelanguages; # language code to name lookup
+my $language_code_pattern = '[a-zA-Z]+(?:_[a-zA-Z]+)?';
memoize("istranslatable");
memoize("_istranslation");
sub import {
hook(type => "getsetup", id => "po", call => \&getsetup);
- hook(type => "checkconfig", id => "po", call => \&checkconfig);
+ hook(type => "checkconfig", id => "po", call => \&checkconfig,
+ last => 1);
hook(type => "needsbuild", id => "po", call => \&needsbuild);
hook(type => "scan", id => "po", call => \&scan, last => 1);
hook(type => "filter", id => "po", call => \&filter);
hook(type => "pagetemplate", id => "po", call => \&pagetemplate, last => 1);
hook(type => "rename", id => "po", call => \&renamepages, first => 1);
hook(type => "delete", id => "po", call => \&mydelete);
- hook(type => "change", id => "po", call => \&change);
+ hook(type => "rendered", id => "po", call => \&rendered);
hook(type => "checkcontent", id => "po", call => \&checkcontent);
hook(type => "canremove", id => "po", call => \&canremove);
hook(type => "canrename", id => "po", call => \&canrename);
inject(name => "IkiWiki::urlto", call => \&myurlto);
$origsubs{'cgiurl'}=\&IkiWiki::cgiurl;
inject(name => "IkiWiki::cgiurl", call => \&mycgiurl);
- $origsubs{'rootpage'}=\&IkiWiki::rootpage;
- inject(name => "IkiWiki::rootpage", call => \&myrootpage);
+ if (IkiWiki->can('rootpage')) {
+ $origsubs{'rootpage'}=\&IkiWiki::rootpage;
+ inject(name => "IkiWiki::rootpage", call => \&myrootpage)
+ if defined $origsubs{'rootpage'};
+ }
$origsubs{'isselflink'}=\&IkiWiki::isselflink;
inject(name => "IkiWiki::isselflink", call => \&myisselflink);
}
else {
$master_language_code=$config{po_master_language}{code};
$master_language_name=$config{po_master_language}{name};
+ $config{po_master_language}=joinlangpair($master_language_code, $master_language_name);
}
}
if (! defined $master_language_code) {
}
if (ref $config{po_slave_languages} eq 'ARRAY') {
- my %slaves;
foreach my $pair (@{$config{po_slave_languages}}) {
my ($code, $name)=splitlangpair($pair);
- if (defined $code) {
+ if (defined $code && ! exists $slavelanguages{$code}) {
push @slavelanguages, $code;
- $slaves{$code} = $name;
+ $slavelanguages{$code} = $name;
}
}
- $config{po_slave_languages} = \%slaves;
}
elsif (ref $config{po_slave_languages} eq 'HASH') {
+ %slavelanguages=%{$config{po_slave_languages}};
@slavelanguages = sort {
$config{po_slave_languages}->{$a} cmp $config{po_slave_languages}->{$b};
- } keys %{$config{po_slave_languages}};
+ } keys %slavelanguages;
+ $config{po_slave_languages}=[
+ map { joinlangpair($_, $slavelanguages{$_}) } @slavelanguages
+ ]
}
- delete $config{po_slave_languages}{$master_language_code};
+ delete $slavelanguages{$master_language_code};
map {
islanguagecode($_)
if ($template->query(name => "istranslatable")) {
$template->param(istranslatable => istranslatable($page));
}
+ my $lang_code = istranslation($page) ? lang($page) : $master_language_code;
+ if ($template->query(name => "lang_code")) {
+ $template->param(lang_code => $lang_code);
+ }
+ if ($template->query(name => "html_lang_code")) {
+ $template->param(html_lang_code => htmllangcode($lang_code));
+ }
+ if ($template->query(name => "html_lang_dir")) {
+ $template->param(html_lang_dir => htmllangdir($lang_code));
+ }
+ if ($template->query(name => "lang_name")) {
+ $template->param(lang_name => languagename($lang_code));
+ }
if ($template->query(name => "HOMEPAGEURL")) {
$template->param(homepageurl => homepageurl($page));
}
&& $masterpage eq "index") {
$template->param('parentlinks' => []);
}
- if (ishomepage($page) && $template->query(name => "title")) {
+ if (ishomepage($page) && $template->query(name => "title")
+ && !$template->param("title_overridden")) {
$template->param(title => $config{wikiname});
}
}
map { deletetranslations($_) } grep istranslatablefile($_), @deleted;
}
-sub change (@) {
+sub rendered (@) {
my @rendered=@_;
my $updated_po_files=0;
# their buttons, which is why this hook must be run last.
# The canrename/canremove hooks already ensure this is forbidden
# at the backend level, so this is only UI sugar.
- if (istranslation($form->field("page"))) {
+ if (istranslation(scalar $form->field("page"))) {
map {
for (my $i = 0; $i < @{$params{buttons}}; $i++) {
if (@{$params{buttons}}[$i] eq $_) {
return $res;
}
-sub mytargetpage ($$) {
+sub mytargetpage ($$;$) {
my $page=shift;
my $ext=shift;
+ my $filename=shift;
if (istranslation($page) || istranslatable($page)) {
my ($masterpage, $lang) = (masterpage($page), lang($page));
- if (! $config{usedirs} || $masterpage eq 'index') {
+ if (defined $filename) {
+ return $masterpage . "/" . $filename . "." . $lang . "." . $ext;
+ }
+ elsif (! $config{usedirs} || $masterpage eq 'index') {
return $masterpage . "." . $lang . "." . $ext;
}
else {
return $masterpage . "/index." . $lang . "." . $ext;
}
}
- return $origsubs{'targetpage'}->($page, $ext);
+ return $origsubs{'targetpage'}->($page, $ext, $filename);
}
-sub myurlto ($$;$) {
+sub myurlto ($;$$) {
my $to=shift;
my $from=shift;
my $absolute=shift;
if (! length $to
&& $config{po_link_to} eq "current"
&& istranslatable('index')) {
- return IkiWiki::beautify_urlpath(IkiWiki::baseurl($from) . "index." . lang($from) . ".$config{htmlext}");
+ if (defined $from) {
+ return IkiWiki::beautify_urlpath(IkiWiki::baseurl($from) . "index." . lang($from) . ".$config{htmlext}");
+ }
+ else {
+ return $origsubs{'urlto'}->($to,$from,$absolute);
+ }
}
# avoid using our injected beautify_urlpath if run by cgi_editpage,
# so that one is redirected to the just-edited page rather than to the
&& pagetype($file) eq 'po';
return 0 if $file =~ /\.pot$/;
- my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/);
+ my ($masterpage, $lang) = ($page =~ /(.*)[.]($language_code_pattern)$/);
return 0 unless defined $masterpage && defined $lang
&& length $masterpage && length $lang
&& defined $pagesources{$masterpage}
- && defined $config{po_slave_languages}{$lang};
+ && defined $slavelanguages{$lang};
return (maybe_add_leading_slash($masterpage, $hasleadingslash), $lang)
if istranslatable($masterpage);
return $master_language_code;
}
+sub htmllangcode ($) {
+ (my $lang = shift) =~ tr/_/-/;
+ return $lang;
+}
+
+sub htmllangdir ($) {
+ my $lang = shift;
+ if ($lang =~ /^(ar|fa|he)/) {
+ return 'rtl';
+ }
+ return 'ltr';
+}
+
sub islanguagecode ($) {
my $code=shift;
- return $code =~ /^[a-z]{2}$/;
+ return $code =~ /^$language_code_pattern$/;
}
sub otherlanguage_page ($$) {
}
if (-e $pofile) {
- system("msgmerge", "--previous", "-q", "-U", "--backup=none", $pofile, $potfile) == 0
- or error("po(refreshpofiles) ".
- sprintf(gettext("failed to update %s"),
- $pofile));
+ if (! (system("msgmerge", "--previous", "-q", "-U", "--backup=none", $pofile, $potfile) == 0)) {
+ print STDERR ("po(refreshpofiles) ". sprintf(gettext("failed to update %s"), $pofile));
+ }
}
else {
File::Copy::syscopy($potfile,$pofile)
return $master_language_name
if $code eq $master_language_code;
- return $config{po_slave_languages}{$code}
- if defined $config{po_slave_languages}{$code};
+ return $slavelanguages{$code}
+ if defined $slavelanguages{$code};
return;
}
push @ret, {
url => urlto_with_orig_beautiful_urlpath(masterpage($page), $page),
code => $master_language_code,
+ html_code => htmllangcode($master_language_code),
+ html_dir => htmllangdir($master_language_code),
language => $master_language_name,
master => 1,
};
push @ret, {
url => urlto_with_orig_beautiful_urlpath($otherpage, $page),
code => $lang,
+ html_code => htmllangcode($lang),
+ html_dir => htmllangdir($lang),
language => languagename($lang),
percent => percenttranslated($otherpage),
}
IkiWiki::rcs_remove($_);
}
else {
- IkiWiki::prune("$config{srcdir}/$_");
+ IkiWiki::prune("$config{srcdir}/$_", $config{srcdir});
}
} @todelete;
# how to disable options is not consistent across po4a modules
$options{includessi} = '';
$options{includeexternal} = 0;
+ $options{ontagerror} = 'warn';
}
elsif ($pagetype eq 'mdwn') {
$options{markdown} = 1;
sub splitlangpair ($) {
my $pair=shift;
- my ($code, $name) = ( $pair =~ /^([a-z]{2})\|(.+)$/ );
+ my ($code, $name) = ( $pair =~ /^($language_code_pattern)\|(.+)$/ );
if (! defined $code || ! defined $name ||
! length $code || ! length $name) {
# not a fatal error to avoid breaking if used with web setup
- print STDERR sprintf(gettext("%s has invalid syntax: must use CODE|NAME"),
- $pair)."\n";
+ warn sprintf(gettext("%s has invalid syntax: must use CODE|NAME"),
+ $pair);
}
return $code, $name;
}
+sub joinlangpair ($$) {
+ my $code=shift;
+ my $name=shift;
+
+ return "$code|$name";
+}
+
# ,----
# | PageSpecs
# `----
my $regexp=IkiWiki::glob2re($wanted);
my $lang=IkiWiki::Plugin::po::lang($page);
- if ($lang !~ /^$regexp$/i) {
+ if ($lang !~ $regexp) {
return IkiWiki::FailReason->new("file language is $lang, not $wanted");
}
else {