X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/196f03a98744db0db4f5218bf243d208f245f7a9..66bc27b485e6dd167d0394db18a078d5b7977ae3:/IkiWiki/Plugin/po.pm diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 157575483..daac95eb1 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -10,6 +10,16 @@ use warnings; use strict; use IkiWiki 3.00; use Encode; +BEGIN { + eval 'use Locale::Po4a::Common qw(nowrapi18n)'; + if ($@) { + warning(sprintf(gettext('%s is too old, can not disable %s; '. + 'a denial of service can thus be '. + 'triggered by malicious content'), + 'Locale::Po4a', 'Text::WrapI18N')); + eval 'use Locale::Po4a::Common'; + } +} use Locale::Po4a::Chooser; use Locale::Po4a::Po; use File::Basename; @@ -39,7 +49,7 @@ sub import { hook(type => "rename", id => "po", call => \&renamepages, first => 1); hook(type => "delete", id => "po", call => \&mydelete); hook(type => "change", id => "po", call => \&change); - hook(type => "cansave", id => "po", call => \&cansave); + hook(type => "checkcontent", id => "po", call => \&checkcontent); hook(type => "canremove", id => "po", call => \&canremove); hook(type => "canrename", id => "po", call => \&canrename); hook(type => "editcontent", id => "po", call => \&editcontent); @@ -56,6 +66,8 @@ sub import { inject(name => "IkiWiki::urlto", call => \&myurlto); $origsubs{'nicepagetitle'}=\&IkiWiki::nicepagetitle; inject(name => "IkiWiki::nicepagetitle", call => \&mynicepagetitle); + $origsubs{'cgiurl'}=\&IkiWiki::cgiurl; + inject(name => "IkiWiki::cgiurl", call => \&mycgiurl); } @@ -355,6 +367,42 @@ sub mydelete(@) { sub change(@) { my @rendered=@_; + # All meta titles are first extracted at scan time, i.e. before we turn + # PO files back into translated markdown; escaping of double-quotes in + # PO files breaks the meta plugin's parsing enough to save ugly titles + # to %pagestate at this time. + # + # Then, at render time, every page's passes on row through the Great + # Rendering Chain (filter->preprocess->linkify->htmlize), and the meta + # plugin's preprocess hook is this time in a position to correctly + # extract the titles from slave pages. + # + # This is, unfortunately, too late: if the page A, linking to the page B, + # is rendered before B, it will display the wrongly-extracted meta title + # as the link text to B. + # + # On the one hand, such a corner case only happens on rebuild: on + # refresh, every rendered page is fixed to contain correct meta titles. + # On the other hand, it can take some time to get every page fixed. + # We therefore re-render every rendered page after a rebuild to fix them + # at once. As this more or less doubles the time needed to rebuild the + # wiki, we do so only when really needed. + + if (scalar @rendered + && exists $config{rebuild} && defined $config{rebuild} && $config{rebuild} + && UNIVERSAL::can("IkiWiki::Plugin::meta", "getsetup") + && exists $config{meta_overrides_page_title} + && defined $config{meta_overrides_page_title} + && $config{meta_overrides_page_title}) { + debug(sprintf(gettext("re-rendering all pages to fix meta titles"))); + resetalreadyfiltered(); + require IkiWiki::Render; + foreach my $file (@rendered) { + debug(sprintf(gettext("rendering %s"), $file)); + IkiWiki::render($file); + } + } + my $updated_po_files=0; # Refresh/create POT and PO files as needed. @@ -388,11 +436,11 @@ sub change(@) { } } -sub cansave ($$$$) { - my ($page, $content, $cgi, $session) = (shift, shift, shift, shift); +sub checkcontent (@) { + my %params=@_; - if (istranslation($page)) { - my $res = isvalidpo($content); + if (istranslation($params{page})) { + my $res = isvalidpo($params{content}); if ($res) { return undef; } @@ -599,6 +647,16 @@ sub mynicepagetitle ($;$) { return $res.' ('.percenttranslated($page).' %)'; } +sub mycgiurl (@) { + my %params=@_; + + # slave pages have no subpages + if (istranslation($params{'from'})) { + $params{'from'} = masterpage($params{'from'}); + } + return $origsubs{'cgiurl'}->(%params); +} + # ,---- # | Blackboxes for private data # `---- @@ -653,6 +711,7 @@ sub istranslatablefile ($) { return 0 unless defined $file; return 0 if (defined pagetype($file) && pagetype($file) eq 'po'); return 0 if $file =~ /\.pot$/; + return 0 unless -e "$config{srcdir}/$file"; # underlay dirs may be read-only return 1 if pagespec_match(pagename($file), $config{po_translatable_pages}); return; } @@ -668,6 +727,7 @@ sub istranslatable ($) { sub _istranslation ($) { my $page=shift; + $page='' unless (defined $page && length $page); my $hasleadingslash = ($page=~s#^/##); my $file=$pagesources{$page}; return 0 unless (defined $file