]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/po.pm
po: redesign (once more) automatic POT/PO files update
[ikiwiki.git] / IkiWiki / Plugin / po.pm
index 1ef332d83b912c30eea567d116fe6b678cb549e1..c8ec37c228378d600ae526086b5fe97fb2ac503d 100644 (file)
@@ -19,6 +19,7 @@ use File::Temp;
 use Memoize;
 
 my %translations;
+my @origneedsbuild;
 our %filtered;
 
 memoize("_istranslation");
@@ -38,6 +39,7 @@ sub import { #{{{
        hook(type => "filter", id => "po", call => \&filter);
        hook(type => "htmlize", id => "po", call => \&htmlize);
        hook(type => "pagetemplate", id => "po", call => \&pagetemplate, last => 1);
+       hook(type => "change", id => "po", call => \&change);
        hook(type => "editcontent", id => "po", call => \&editcontent);
 
        $origsubs{'bestlink'}=\&IkiWiki::bestlink;
@@ -103,9 +105,12 @@ sub checkconfig () { #{{{
                        error(sprintf(gettext("Must specify %s"), $field));
                }
        }
+       if (! (keys %{$config{po_slave_languages}})) {
+               error(gettext("At least one slave language must be defined in po_slave_languages"));
+       }
        map {
                islanguagecode($_)
-                   or error(sprintf(gettext("%s is not a valid language code"), $_));
+                       or error(sprintf(gettext("%s is not a valid language code"), $_));
        } ($config{po_master_language}{code}, keys %{$config{po_slave_languages}});
        if (! exists $config{po_translatable_pages} ||
            ! defined $config{po_translatable_pages}) {
@@ -115,9 +120,9 @@ sub checkconfig () { #{{{
            ! defined $config{po_link_to}) {
                $config{po_link_to}='default';
        }
-       elsif ($config{po_link_to} != 'default'
-           && $config{po_link_to} != 'current'
-           && $config{po_link_to} != 'negotiated') {
+       elsif (! grep {
+                       $config{po_link_to} eq $_
+               } ('default', 'current', 'negotiated')) {
                warn(sprintf(gettext('po_link_to=%s is not a valid setting, falling back to po_link_to=default'),
                                $config{po_link_to}));
                $config{po_link_to}='default';
@@ -164,6 +169,7 @@ sub refreshpot ($) { #{{{
        $doc->{TT}{po_out}->set_charset('utf-8');
        # do the actual work
        $doc->parse;
+       IkiWiki::prep_writefile(basename($potfile),dirname($potfile));
        $doc->writepo($potfile);
 } #}}}
 
@@ -175,6 +181,7 @@ sub refreshpofiles ($@) { #{{{
        error("[po/refreshpofiles] POT file ($potfile) does not exist") unless (-e $potfile);
 
        foreach my $pofile (@pofiles) {
+               IkiWiki::prep_writefile(basename($pofile),dirname($pofile));
                if (-e $pofile) {
                        system("msgmerge", "-U", "--backup=none", $pofile, $potfile) == 0
                                or error("[po/refreshpofiles:$pofile] failed to update");
@@ -189,56 +196,12 @@ sub refreshpofiles ($@) { #{{{
 sub needsbuild () { #{{{
        my $needsbuild=shift;
 
-       # build %translations, using istranslation's side-effect
-       foreach my $page (keys %pagesources) {
-               istranslation($page);
-       }
-
-       # refresh/create POT and PO files as needed
-       my $updated_po_files=0;
-       foreach my $page (keys %pagesources) {
-               if (istranslatable($page)) {
-                       my $pageneedsbuild = grep { $_ eq $pagesources{$page} } @$needsbuild;
-                       my $updated_pot_file=0;
-                       my $file=srcfile($pagesources{$page});
-                       if ($pageneedsbuild || ! -e potfile($file)) {
-                               refreshpot($file);
-                               $updated_pot_file=1;
-                       }
-                       my @pofiles;
-                       foreach my $lang (keys %{$config{po_slave_languages}}) {
-                               my $pofile=pofile($file, $lang);
-                               my $pofile_rel=pofile($pagesources{$page}, $lang);
-                               if ($pageneedsbuild || $updated_pot_file || ! -e $pofile) {
-                                       push @pofiles, $pofile;
-                                       push @$needsbuild, $pofile_rel
-                                         unless grep { $_ eq $pofile_rel } @$needsbuild;
-                               }
-                       }
-                       if (@pofiles) {
-                               refreshpofiles($file, @pofiles) ;
-                               map { IkiWiki::rcs_add($_); } @pofiles if ($config{rcs});
-                               $updated_po_files = 1;
-                       }
-               }
-       }
+       # backup @needsbuild content so that change() can know whether
+       # a given master page was rendered because its source file was changed
+       @origneedsbuild=(@$needsbuild);
 
-       # check staged changes in
-       if ($updated_po_files) {
-               if ($config{rcs}) {
-                       IkiWiki::disable_commit_hook();
-                       IkiWiki::rcs_commit_staged(gettext("updated PO files"),
-                               "refreshpofiles", "127.0.0.1");
-                       IkiWiki::enable_commit_hook();
-                       IkiWiki::rcs_update();
-               }
-               # refresh module's private variables
-               undef %filtered;
-               undef %translations;
-               foreach my $page (keys %pagesources) {
-                       istranslation($page);
-               }
-       }
+       # build %translations, using istranslation's side-effect
+       map istranslation($_), (keys %pagesources);
 
        # make existing translations depend on the corresponding master page
        foreach my $master (keys %translations) {
@@ -502,6 +465,54 @@ sub pagetemplate (@) { #{{{
        }
 } # }}}
 
+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