+ my $page=$params{page};
+ my $destpage=$params{destpage};
+ my $template=$params{template};
+
+ my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/) if istranslation($page);
+
+ if (istranslation($page) && $template->query(name => "percenttranslated")) {
+ $template->param(percenttranslated => percenttranslated($page));
+ }
+ if ($template->query(name => "istranslation")) {
+ $template->param(istranslation => istranslation($page));
+ }
+ if ($template->query(name => "istranslatable")) {
+ $template->param(istranslatable => istranslatable($page));
+ }
+ if ($template->query(name => "otherlanguages")) {
+ $template->param(otherlanguages => [otherlanguages($page)]);
+ if (istranslatable($page)) {
+ foreach my $translation (values %{$translations{$page}}) {
+ add_depends($page, $translation);
+ }
+ }
+ elsif (istranslation($page)) {
+ add_depends($page, $masterpage);
+ foreach my $translation (values %{$translations{$masterpage}}) {
+ add_depends($page, $translation);
+ }
+ }
+ }
+ # Rely on IkiWiki::Render's genpage() to decide wether
+ # a discussion link should appear on $page; this is not
+ # totally accurate, though: some broken links may be generated
+ # when cgiurl is disabled.
+ # This compromise avoids some code duplication, and will probably
+ # prevent future breakage when ikiwiki internals change.
+ # Known limitations are preferred to future random bugs.
+ if ($template->param('discussionlink') && istranslation($page)) {
+ $template->param('discussionlink' => htmllink(
+ $page,
+ $destpage,
+ $masterpage . '/' . gettext("Discussion"),
+ noimageinline => 1,
+ forcesubpage => 0,
+ linktext => gettext("Discussion"),
+ ));
+ }
+ # remove broken parentlink to ./index.html on home page's translations
+ if ($template->param('parentlinks')
+ && istranslation($page)
+ && $masterpage eq "index") {
+ $template->param('parentlinks' => []);
+ }
+} # }}}
+
+sub change(@) { #{{{
+ my @rendered=@_;
+
+ my $updated_po_files=0;
+
+ # Refresh/create POT and PO files as needed.
+ foreach my $page (map pagename($_), @rendered) {
+ next unless istranslatable($page);
+ my $file=srcfile($pagesources{$page});
+ my $updated_pot_file=0;
+ if ((grep { $_ eq $pagesources{$page} } @origneedsbuild)
+ || ! -e potfile($file)) {
+ refreshpot($file);
+ $updated_pot_file=1;
+ }
+ my @pofiles;
+ foreach my $lang (keys %{$config{po_slave_languages}}) {
+ my $pofile=pofile($file, $lang);
+ if ($updated_pot_file || ! -e $pofile) {
+ push @pofiles, $pofile;
+ }
+ }
+ if (@pofiles) {
+ refreshpofiles($file, @pofiles);
+ map { IkiWiki::rcs_add($_); } @pofiles if ($config{rcs});
+ $updated_po_files=1;
+ }
+ }
+
+ if ($updated_po_files) {
+ # Check staged changes in.
+ if ($config{rcs}) {
+ IkiWiki::disable_commit_hook();
+ IkiWiki::rcs_commit_staged(gettext("updated PO files"),
+ "IkiWiki::Plugin::po::change", "127.0.0.1");
+ IkiWiki::enable_commit_hook();
+ IkiWiki::rcs_update();
+ }
+ # Reinitialize module's private variables.
+ undef %filtered;
+ undef %translations;
+ # Trigger a wiki refresh.
+ require IkiWiki::Render;
+ IkiWiki::refresh();
+ IkiWiki::saveindex();
+ }
+} #}}}
+
+sub editcontent () { #{{{
+ my %params=@_;
+ # as we're previewing or saving a page, the content may have
+ # changed, so tell the next filter() invocation it must not be lazy
+ if (exists $filtered{$params{page}}{$params{page}}) {
+ delete $filtered{$params{page}}{$params{page}};
+ }
+ return $params{content};
+} #}}}
+
+sub istranslatable ($) { #{{{
+ my $page=shift;
+
+ my $file=$pagesources{$page};
+
+ if (! defined $file
+ || (defined pagetype($file) && pagetype($file) eq 'po')
+ || $file =~ /\.pot$/) {
+ return 0;
+ }
+ return pagespec_match($page, $config{po_translatable_pages});
+} #}}}
+
+sub _istranslation ($) { #{{{
+ my $page=shift;
+
+ my $file=$pagesources{$page};