]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/po.pm
po(formbuilder_setup): use a template to display the warning
[ikiwiki.git] / IkiWiki / Plugin / po.pm
index 35e7c13fffa1622e2060f3a03c8a07b9c9b8ca44..c8b5e8fdef481b2dc9ba35afe22e5b89bb1d9a1e 100644 (file)
@@ -8,7 +8,7 @@ package IkiWiki::Plugin::po;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use Encode;
 use Locale::Po4a::Chooser;
 use Locale::Po4a::Po;
@@ -43,6 +43,7 @@ sub import {
        hook(type => "canremove", id => "po", call => \&canremove);
        hook(type => "canrename", id => "po", call => \&canrename);
        hook(type => "editcontent", id => "po", call => \&editcontent);
+       hook(type => "formbuilder_setup", id => "po", call => \&formbuilder_setup);
 
        $origsubs{'bestlink'}=\&IkiWiki::bestlink;
        inject(name => "IkiWiki::bestlink", call => \&mybestlink);
@@ -388,11 +389,12 @@ sub cansave ($$$$) {
        my ($page, $content, $cgi, $session) = (shift, shift, shift, shift);
 
        if (istranslation($page)) {
-               if (defined po_to_markup($page, $content, "nonfatal")) {
+               my $res = isvalidpo($content);
+               if ($res) {
                        return undef;
                }
                else {
-                       return "Could not parse this page's content; is this valid gettext?";
+                       return "$res";
                }
        }
        return undef;
@@ -438,6 +440,18 @@ sub editcontent () {
        return $params{content};
 }
 
+sub formbuilder_setup (@) {
+       my %params=@_;
+       my $form=$params{form};
+       my $q=$params{cgi};
+
+       return unless (defined $form->field("do") && $form->field("do") eq "create");
+
+       my $template=template("pocreatepage.tmpl");
+       $template->param(LANG => $config{po_master_language}{name});
+       $form->tmpl_param(message => $template->output);
+}
+
 
 # ,----
 # | Injected functions
@@ -908,7 +922,7 @@ sub po_to_markup ($$;$) {
                                     UNLINK => 1)->filename;
 
        sub failure ($) {
-               my $msg = '[po/filter:'.$page.'] ' . shift;
+               my $msg = '[po/po_to_markup:'.$page.'] ' . shift;
                if ($nonfatal) {
                        warn $msg;
                        return undef;
@@ -942,6 +956,48 @@ sub po_to_markup ($$;$) {
        return $content;
 }
 
+# returns a SuccessReason or FailReason object
+sub isvalidpo ($) {
+       my $content = shift;
+
+       # NB: we don't use po_to_markup here, since Po4a parser does
+       # not mind invalid PO content
+       $content = '' unless defined $content;
+       $content = decode_utf8(encode_utf8($content));
+
+       # There are incompatibilities between some File::Temp versions
+       # (including 0.18, bundled with Lenny's perl-modules package)
+       # and others (e.g. 0.20, previously present in the archive as
+       # a standalone package): under certain circumstances, some
+       # return a relative filename, whereas others return an absolute one;
+       # we here use this module in a way that is at least compatible
+       # with 0.18 and 0.20. Beware, hit'n'run refactorers!
+       my $infile = new File::Temp(TEMPLATE => "ikiwiki-po-isvalidpo.XXXXXXXXXX",
+                                   DIR => File::Spec->tmpdir,
+                                   UNLINK => 1)->filename;
+
+       sub failure ($) {
+               my $msg = '[po/isvalidpo] ' . shift;
+               unlink $infile;
+               return IkiWiki::FailReason->new("$msg");
+       }
+
+       writefile(basename($infile), File::Spec->tmpdir, $content)
+               or return failure("failed to write $infile");
+
+       my $res = (system("msgfmt", "--check", $infile, "-o", "/dev/null") == 0);
+
+       # Unlinking should happen automatically, thanks to File::Temp,
+       # but it does not work here, probably because of the way writefile()
+       # and Locale::Po4a::write() work.
+       unlink $infile;
+
+       if ($res) {
+           return IkiWiki::SuccessReason->new("valid gettext data");
+       }
+       return IkiWiki::FailReason->new("invalid gettext data");
+}
+
 # ,----
 # | PageSpec's
 # `----