+ 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;
+}
+
+sub homepageurl (;$) {
+ my $page=shift;
+
+ return urlto('', $page);
+}
+
+sub deletetranslations ($) {
+ my $deletedmasterfile=shift;
+
+ my $deletedmasterpage=pagename($deletedmasterfile);
+ my @todelete;
+ map {
+ my $file = newpagefile($deletedmasterpage.'.'.$_, 'po');
+ my $absfile = "$config{srcdir}/$file";
+ if (-e $absfile && ! -l $absfile && ! -d $absfile) {
+ push @todelete, $file;
+ }
+ } keys %{$config{po_slave_languages}};
+
+ map {
+ if ($config{rcs}) {
+ IkiWiki::rcs_remove($_);
+ }
+ else {
+ IkiWiki::prune("$config{srcdir}/$_");
+ }
+ } @todelete;
+
+ if (scalar @todelete) {
+ commit_and_refresh(
+ gettext("removed obsolete PO files"),
+ "IkiWiki::Plugin::po::deletetranslations");
+ }
+}
+
+sub commit_and_refresh ($$) {
+ my ($msg, $author) = (shift, shift);
+
+ if ($config{rcs}) {
+ IkiWiki::disable_commit_hook();
+ IkiWiki::rcs_commit_staged($msg, $author, "127.0.0.1");
+ IkiWiki::enable_commit_hook();
+ IkiWiki::rcs_update();
+ }
+ # Reinitialize module's private variables.
+ resetalreadyfiltered();
+ resettranslationscache();
+ flushmemoizecache();
+ # Trigger a wiki refresh.
+ require IkiWiki::Render;
+ # without preliminary saveindex/loadindex, refresh()
+ # complains about a lot of uninitialized variables
+ IkiWiki::saveindex();
+ IkiWiki::loadindex();
+ IkiWiki::refresh();
+ IkiWiki::saveindex();
+}
+
+# ,----
+# | PageSpec's
+# `----
+
+package IkiWiki::PageSpec;
+use warnings;
+use strict;
+use IkiWiki 2.00;
+
+sub match_istranslation ($;@) {
+ my $page=shift;
+
+ if (IkiWiki::Plugin::po::istranslation($page)) {
+ return IkiWiki::SuccessReason->new("is a translation page");
+ }
+ else {
+ return IkiWiki::FailReason->new("is not a translation page");
+ }
+}
+
+sub match_istranslatable ($;@) {
+ my $page=shift;
+
+ if (IkiWiki::Plugin::po::istranslatable($page)) {
+ return IkiWiki::SuccessReason->new("is set as translatable in po_translatable_pages");
+ }
+ else {
+ return IkiWiki::FailReason->new("is not set as translatable in po_translatable_pages");
+ }
+}
+
+sub match_lang ($$;@) {
+ my $page=shift;
+ my $wanted=shift;
+
+ my $regexp=IkiWiki::glob2re($wanted);
+ my $lang=IkiWiki::Plugin::po::lang($page);
+ if ($lang!~/^$regexp$/i) {
+ return IkiWiki::FailReason->new("file language is $lang, not $wanted");
+ }
+ else {
+ return IkiWiki::SuccessReason->new("file language is $wanted");
+ }
+}
+
+sub match_currentlang ($$;@) {
+ my $page=shift;
+ shift;
+ my %params=@_;
+
+ return IkiWiki::FailReason->new("no location provided") unless exists $params{location};