]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - IkiWiki/Plugin/po.pm
po: new po_translation_status_in_links option
[git.ikiwiki.info.git] / IkiWiki / Plugin / po.pm
index 60a9f26322cdb34dae9f71e1148eb47f158ee7a0..33bc2b0577153b20815fb4dd1b8e9519b7972be5 100644 (file)
@@ -35,6 +35,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 => "rename", id => "po", call => \&renamepages);
        hook(type => "delete", id => "po", call => \&mydelete);
        hook(type => "change", id => "po", call => \&change);
        hook(type => "editcontent", id => "po", call => \&editcontent);
@@ -47,6 +48,8 @@ sub import { #{{{
        inject(name => "IkiWiki::targetpage", call => \&mytargetpage);
        $origsubs{'urlto'}=\&IkiWiki::urlto;
        inject(name => "IkiWiki::urlto", call => \&myurlto);
+       $origsubs{'nicepagetitle'}=\&IkiWiki::nicepagetitle;
+       inject(name => "IkiWiki::nicepagetitle", call => \&mynicepagetitle);
 } #}}}
 
 
@@ -107,6 +110,13 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
+               po_translation_status_in_links => {
+                       type => "boolean",
+                       example => 1,
+                       description => "display translation status in links to translations",
+                       safe => 1,
+                       rebuild => 1,
+               },
 } #}}}
 
 sub checkconfig () { #{{{
@@ -141,6 +151,10 @@ sub checkconfig () { #{{{
                warn(gettext('po_link_to=negotiated requires usedirs to be enabled, falling back to po_link_to=default'));
                $config{po_link_to}='default';
        }
+       if (! exists $config{po_translation_status_in_links} ||
+           ! defined $config{po_translation_status_in_links}) {
+               $config{po_translation_status_in_links}=1;
+       }
        push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/;
 } #}}}
 
@@ -326,10 +340,35 @@ sub pagetemplate (@) { #{{{
        }
 } # }}}
 
+# Add the renamed page translations to the list of to-be-renamed pages.
+# Save information about master page rename, so that:
+# - our delete hook can ignore the translations not renamed already
+# - our change hook can rename the translations accordingly.
+sub renamepages() { #{{{
+       my $torename=shift;
+       my @torename=@{$torename};
+
+       foreach my $rename (@torename) {
+               next unless istranslatable($rename->{src});
+               my %otherpages=%{otherlanguages($rename->{src})};
+               while (my ($lang, $otherpage) = each %otherpages) {
+                       push @{$torename}, {
+                               src => $otherpage,
+                               srcfile => $pagesources{$otherpage},
+                               dest => otherlanguage($rename->{dest}, $lang),
+                               destfile => $rename->{dest}.".".$lang.".po",
+                               required => 0,
+                       };
+               }
+       }
+} #}}}
+
 sub mydelete(@) { #{{{
        my @deleted=@_;
 
-       map { deletetranslations($_) } grep istranslatablefile($_), @deleted;
+       map {
+               deletetranslations($_);
+       } grep { istranslatablefile($_) } @deleted;
 } #}}}
 
 sub change(@) { #{{{
@@ -363,26 +402,9 @@ sub change(@) { #{{{
        }
 
        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();
-               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();
+               commit_and_refresh(
+                       gettext("updated PO files"),
+                       "IkiWiki::Plugin::po::change");
        }
 } #}}}
 
@@ -456,9 +478,34 @@ sub myurlto ($$;$) { #{{{
            && istranslatable('index')) {
                return IkiWiki::beautify_urlpath(IkiWiki::baseurl($from) . "index." . lang($from) . ".$config{htmlext}");
        }
-       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
+       # negociated translation; to prevent unnecessary fiddling with caller/inject,
+       # we only do so when our beautify_urlpath would actually do what we want to
+       # avoid, i.e. when po_link_to = negotiated
+       if ($config{po_link_to} eq "negotiated") {
+               my @caller = caller(1);
+               my $run_by_editpage = ($caller[3] eq "IkiWiki::cgi_editpage");
+               inject(name => "IkiWiki::beautify_urlpath", call => $origsubs{'beautify_urlpath'})
+                       if $run_by_editpage;
+               my $res = $origsubs{'urlto'}->($to,$from,$absolute);
+               inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath)
+                       if $run_by_editpage;
+               return $res;
+       }
+       else {
+               return $origsubs{'urlto'}->($to,$from,$absolute)
+       }
 } #}}}
 
+sub mynicepagetitle ($;$) { #{{{
+       my ($page, $unescaped) = (shift, shift);
+
+       my $res = $origsubs{'nicepagetitle'}->($page, $unescaped);
+       return $res unless istranslation($page);
+       return $res unless $config{po_translation_status_in_links};
+       return $res.' ('.percenttranslated($page).' %)';
+} #}}}
 
 # ,----
 # | Blackboxes for private data
@@ -496,7 +543,6 @@ sub myurlto ($$;$) { #{{{
        } #}}}
 }
 
-
 # ,----
 # | Helper functions
 # `----
@@ -698,6 +744,7 @@ sub urlto_with_orig_beautiful_urlpath($$) { #{{{
 sub percenttranslated ($) { #{{{
        my $page=shift;
 
+       $page=~s/^\///;
        return gettext("N/A") unless istranslation($page);
        my $file=srcfile($pagesources{$page});
        my $masterfile = srcfile($pagesources{masterpage($page)});
@@ -764,11 +811,56 @@ sub homepageurl (;$) { #{{{
        return urlto('', $page);
 } #}}}
 
-# do *not* implement this until the renamepage hook works
 sub deletetranslations ($) { #{{{
-       my $file=shift;
+       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}};
 
-       debug 'po(deletetranslations): TODO: delete translations of ' . $file;
+       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();
 } #}}}
 
 # ,----