+ my $page=$params{page};
+ my $destpage=$params{destpage};
+ my $template=$params{template};
+
+ my ($masterpage, $lang) = istranslation($page);
+
+ if (istranslation($page) && $template->query(name => "percenttranslated")) {
+ $template->param(percenttranslated => percenttranslated($page));
+ }
+ if ($template->query(name => "istranslation")) {
+ $template->param(istranslation => scalar istranslation($page));
+ }
+ if ($template->query(name => "istranslatable")) {
+ $template->param(istranslatable => istranslatable($page));
+ }
+ if ($template->query(name => "otherlanguages")) {
+ $template->param(otherlanguages => [otherlanguagesloop($page)]);
+ map add_depends($page, $_), (values %{otherlanguages($page)});
+ }
+ # 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.
+ # It works because this hook has the "last" parameter set, to ensure it
+ # runs after parentlinks' own pagetemplate hook.
+ 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;
+ # Only refresh Pot file if it does not exist, or if
+ # $pagesources{$page} was changed: don't if only the HTML was
+ # refreshed, e.g. because of a dependency.
+ if ((grep { $_ eq $pagesources{$page} } @origneedsbuild)
+ || ! -e potfile($file)) {
+ refreshpot($file);
+ $updated_pot_file=1;
+ }
+ my @pofiles;
+ map {
+ push @pofiles, $_ if ($updated_pot_file || ! -e $_);
+ } (pofiles($file));
+ 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.
+ resetalreadyfiltered();
+ resettranslationscache();
+ # 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
+ unsetalreadyfiltered($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};