From a128c256a51392fcf752bf612d83a90e8c68027e Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Jun 2010 23:18:34 +0200 Subject: po: added support for html pagetype ... after having audited the po4a Xml and Xhtml modules for security issues. Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 10 +++++----- doc/plugins/po/discussion.mdwn | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'doc') diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 576d36ec1..585e14383 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -213,16 +213,16 @@ preferred `$EDITOR`, without needing to be online. Markup languages support ------------------------ -[[Markdown|mdwn]] is well supported. Some other markup languages supported -by ikiwiki mostly work, but some pieces of syntax are not rendered -correctly on the slave pages: +[[Markdown|mdwn]] and [[html]] are well supported. Some other markup +languages supported by ikiwiki mostly work, but some pieces of syntax +are not rendered correctly on the slave pages: * [[reStructuredText|rst]]: anonymous hyperlinks and internal cross-references * [[wikitext]]: conversion of newlines to paragraphs * [[creole]]: verbatim text is wrapped, tables are broken -* [[html]] and LaTeX: not supported yet; the dedicated po4a modules - could be used to support them, but they would need a security audit +* LaTeX: not supported yet; the dedicated po4a module + could be used to support it, but it would need a security audit * other markup languages have not been tested. Security diff --git a/doc/plugins/po/discussion.mdwn b/doc/plugins/po/discussion.mdwn index 27683f1ea..73858c818 100644 --- a/doc/plugins/po/discussion.mdwn +++ b/doc/plugins/po/discussion.mdwn @@ -150,6 +150,23 @@ The following analysis was done with his help. variables; according to [[Joey]], this is "Freaky code, but seems ok due to use of `quotementa`". +##### Locale::Po4a::Xhtml + +* does not run any external program +* does not build regexp's from untrusted variables + +=> Seems safe as far as the `includessi` option is disabled; the po +plugin explicitly disables it. + +Relies on Locale::Po4a::Xml` to do most of the work. + +##### Locale::Po4a::Xml + +* does not run any external program +* the `includeexternal` option makes it able to read external files; + the po plugin explicitly disables it +* untrusted variables are escaped when used to build regexp's + ##### Text::WrapI18N `Text::WrapI18N` can cause DoS -- cgit v1.2.3 From 4cf185e781a5f94373b30ec9a0e10dfb626b6d86 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 26 Jun 2010 00:56:06 +0200 Subject: po_slave_languages can now be a hash, if order matters. --- IkiWiki/Plugin/po.pm | 95 +++++++++++++++++++++++++++++++++------------------- doc/plugins/po.mdwn | 13 ++----- 2 files changed, 62 insertions(+), 46 deletions(-) (limited to 'doc') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ab1cc7ae6..7d5dfee03 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -28,6 +28,7 @@ use UNIVERSAL; my %translations; my @origneedsbuild; my %origsubs; +my @slavelanguages; # orderer as in config po_slave_languages memoize("istranslatable"); memoize("_istranslation"); @@ -104,11 +105,11 @@ sub getsetup () { }, po_slave_languages => { type => "string", - example => { + example => [ 'fr' => 'Français', 'es' => 'Español', 'de' => 'Deutsch' - }, + ], description => "slave languages (PO files)", safe => 1, rebuild => 1, @@ -137,6 +138,21 @@ sub checkconfig () { $field, 'po')); } } + + if (ref $config{po_slave_languages} eq 'ARRAY') { + my %slaves; + for (my $i=0; $i<@{$config{po_slave_languages}}; $i = $i + 2) { + $slaves{$config{po_slave_languages}->[$i]} = $config{po_slave_languages}->[$i + 1]; + push @slavelanguages, $config{po_slave_languages}->[$i]; + } + $config{po_slave_languages} = \%slaves; + } + elsif (ref $config{po_slave_languages} eq 'HASH') { + @slavelanguages = sort { + $config{po_slave_languages}->{$a} cmp $config{po_slave_languages}->{$b}; + } keys %{$config{po_slave_languages}}; + } + delete $config{po_slave_languages}{$config{po_master_language}{code}};; map { @@ -197,7 +213,7 @@ sub needsbuild () { # make existing translations depend on the corresponding master page foreach my $master (keys %translations) { - map add_depends($_, $master), values %{otherlanguages($master)}; + map add_depends($_, $master), values %{otherlanguages_pages($master)}; } } @@ -229,7 +245,7 @@ sub scan (@) { # make sure any destpage's translations has # $page in its backlinks push @{$links{$page}}, - values %{otherlanguages($destpage)}; + values %{otherlanguages_pages($destpage)}; } } } @@ -295,7 +311,7 @@ sub pagetemplate (@) { } if ($template->query(name => "otherlanguages")) { $template->param(otherlanguages => [otherlanguagesloop($page)]); - map add_depends($page, $_), (values %{otherlanguages($page)}); + map add_depends($page, $_), (values %{otherlanguages_pages($page)}); } if ($config{discussion} && istranslation($page)) { if ($page !~ /.*\/\Q$config{discussionpage}\E$/i && @@ -348,12 +364,12 @@ sub renamepages (@) { return () unless istranslatable($torename{src}); my @ret; - my %otherpages=%{otherlanguages($torename{src})}; + my %otherpages=%{otherlanguages_pages($torename{src})}; while (my ($lang, $otherpage) = each %otherpages) { push @ret, { src => $otherpage, srcfile => $pagesources{$otherpage}, - dest => otherlanguage($torename{dest}, $lang), + dest => otherlanguage_page($torename{dest}, $lang), destfile => $torename{dest}.".".$lang.".po", required => 0, }; @@ -820,7 +836,7 @@ sub islanguagecode ($) { return $code =~ /^[a-z]{2}$/; } -sub otherlanguage ($$) { +sub otherlanguage_page ($$) { my $page=shift; my $code=shift; @@ -828,17 +844,31 @@ sub otherlanguage ($$) { return masterpage($page) . '.' . $code; } -sub otherlanguages ($) { +# Returns the list of other languages codes: the master language comes first, +# then the codes are ordered the same way as in po_slave_languages, if it is +# an array, or in the language name lexical order, if it is a hash. +sub otherlanguages_codes ($) { my $page=shift; - my %ret; - return \%ret unless istranslation($page) || istranslatable($page); + my @ret; + return \@ret unless istranslation($page) || istranslatable($page); my $curlang=lang($page); foreach my $lang - ($config{po_master_language}{code}, keys %{$config{po_slave_languages}}) { + ($config{po_master_language}{code}, @slavelanguages) { next if $lang eq $curlang; - $ret{$lang}=otherlanguage($page, $lang); + push @ret, $lang; } + return \@ret; +} + +sub otherlanguages_pages ($) { + my $page=shift; + + my %ret; + map { + $ret{$_} = otherlanguage_page($page, $_) + } otherlanguages_codes($page); + return \%ret; } @@ -989,30 +1019,25 @@ sub otherlanguagesloop ($) { my $page=shift; my @ret; - my %otherpages=%{otherlanguages($page)}; - while (my ($lang, $otherpage) = each %otherpages) { - if (istranslation($page) && masterpage($page) eq $otherpage) { - push @ret, { - url => urlto_with_orig_beautiful_urlpath($otherpage, $page), - code => $lang, - language => languagename($lang), - master => 1, - }; - } - elsif (istranslation($otherpage)) { - push @ret, { - url => urlto_with_orig_beautiful_urlpath($otherpage, $page), - code => $lang, - language => languagename($lang), - percent => percenttranslated($otherpage), - } + if (istranslation($page)) { + push @ret, { + url => urlto_with_orig_beautiful_urlpath(masterpage($page), $page), + code => $config{po_master_language}{code}, + language => $config{po_master_language}{name}, + master => 1, + }; + } + foreach my $lang (@{otherlanguages_codes($page)}) { + next if $lang eq $config{po_master_language}{code}; + my $otherpage = otherlanguage_page($page, $lang); + push @ret, { + url => urlto_with_orig_beautiful_urlpath($otherpage, $page), + code => $lang, + language => languagename($lang), + percent => percenttranslated($otherpage), } } - 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; + return @ret; } sub homepageurl (;$) { diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 585e14383..6b2a30786 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -54,10 +54,10 @@ Supported languages `po_slave_languages` is used to set the list of supported "slave" languages, such as: - po_slave_languages => { 'fr' => 'Français', + po_slave_languages => [ 'fr' => 'Français', 'es' => 'Español', 'de' => 'Deutsch', - } + ] Decide which pages are translatable ----------------------------------- @@ -254,15 +254,6 @@ once [[intrigeri]]'s `meta` branch is merged. An integration branch, called `meta-po`, merges [[intrigeri]]'s `po` and `meta` branches, and thus has this additional features. -Language display order ----------------------- - -Jonas pointed out that one might want to control the order that links to -other languages are listed, for various reasons. Currently, there is no -order, as `po_slave_languages` is a hash. It would need to be converted -to an array to support this. (If twere done, twere best done quickly.) ---[[Joey]] - Pagespecs --------- -- cgit v1.2.3 From 924f559e5049a63488a5f2baca610299a7e02957 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 26 Jun 2010 00:59:20 +0200 Subject: typo fix. --- doc/plugins/po.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 6b2a30786..dc0b638e2 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -130,7 +130,7 @@ lighttpd -------- Recent versions of lighttpd should be able to use -`$HTTP["language"]` to configure the translatted pages to be served. +`$HTTP["language"]` to configure the translated pages to be served. See [Lighttpd Issue](http://redmine.lighttpd.net/issues/show/1119) -- cgit v1.2.3 From dcd57dd5c9f3265bb7a78a5696b90976698c43aa Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 29 Jun 2010 15:13:23 +0200 Subject: Add a fullpage arg to filter. Set it to true every time IkiWiki::filter is called on a full page's content. This is a much nicer solution, for the po plugin, than previous whitelisting using caller(). --- IkiWiki.pm | 6 ++++-- IkiWiki/Plugin/editpage.pm | 2 +- IkiWiki/Plugin/inline.pm | 4 ++-- IkiWiki/Plugin/po.pm | 6 ++---- IkiWiki/Plugin/sidebar.pm | 2 +- IkiWiki/Render.pm | 4 ++-- doc/plugins/write.mdwn | 4 +++- 7 files changed, 15 insertions(+), 13 deletions(-) (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index 0457a6c61..7b5fd283d 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1396,14 +1396,16 @@ sub preprocess ($$$;$$) { return $content; } -sub filter ($$$) { +sub filter ($$$;$) { my $page=shift; my $destpage=shift; my $content=shift; + my $fullpage=shift; + $fullpage = 0 unless defined $fullpage; run_hooks(filter => sub { $content=shift->(page => $page, destpage => $destpage, - content => $content); + content => $content, fullpage => $fullpage); }); return $content; diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index 1a04a72b5..706630203 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -187,7 +187,7 @@ sub cgi_editpage ($$) { my $preview=htmlize($page, $page, $type, linkify($page, $page, preprocess($page, $page, - filter($page, $page, $content), 0, 1))); + filter($page, $page, $content, 'fullpage'), 0, 1))); run_hooks(format => sub { $preview=shift->( page => $page, diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm index 715a3d652..a04dd6630 100644 --- a/IkiWiki/Plugin/inline.pm +++ b/IkiWiki/Plugin/inline.pm @@ -403,7 +403,7 @@ sub preprocess_inline (@) { linkify($page, $params{destpage}, preprocess($page, $params{destpage}, filter($page, $params{destpage}, - readfile(srcfile($file))))); + readfile(srcfile($file)), 'fullpage'))); } else { $ret.="\n". @@ -474,7 +474,7 @@ sub get_inline_content ($$) { linkify($page, $destpage, preprocess($page, $destpage, filter($page, $destpage, - readfile(srcfile($file)))))); + readfile(srcfile($file)), 'fullpage')))); $nested--; if (isinternal($page)) { # make inlined text of internal pages searchable diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ac4401e48..93cf6bbdf 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -259,11 +259,9 @@ sub filter (@) { my $page = $params{page}; my $destpage = $params{destpage}; my $content = $params{content}; + my $fullpage = $params{fullpage}; - my @caller = caller(4); - # FIXME: need to whitelist inline as well? - unless ($caller[3] eq "IkiWiki::render" || - $caller[3] eq 'IkiWiki::Plugin::sidebar::sidebar_content') { + unless ($fullpage) { return $content; } diff --git a/IkiWiki/Plugin/sidebar.pm b/IkiWiki/Plugin/sidebar.pm index 2d495db2c..100015cee 100644 --- a/IkiWiki/Plugin/sidebar.pm +++ b/IkiWiki/Plugin/sidebar.pm @@ -89,7 +89,7 @@ sub sidebar_content ($) { return IkiWiki::htmlize($sidebar_page, $page, $sidebar_type, IkiWiki::linkify($sidebar_page, $page, IkiWiki::preprocess($sidebar_page, $page, - IkiWiki::filter($sidebar_page, $page, $content)))); + IkiWiki::filter($sidebar_page, $page, $content, 'fullpage')))); } } diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index a653ab2da..233d093ed 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -232,7 +232,7 @@ sub render ($$) { linkify($page, $page, preprocess($page, $page, filter($page, $page, - readfile($srcfile))))); + readfile($srcfile), 'fullpage')))); my $output=htmlpage($page); writefile($output, $config{destdir}, genpage($page, $content)); @@ -837,7 +837,7 @@ sub commandline_render () { my $content=readfile($srcfile); my $page=pagename($file); $pagesources{$page}=$file; - $content=filter($page, $page, $content); + $content=filter($page, $page, $content, 'fullpage'); $content=preprocess($page, $page, $content); $content=linkify($page, $page, $content); $content=htmlize($page, $page, $type, $content); diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index a921b9a02..15ed08d82 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -200,7 +200,9 @@ value is ignored. Runs on the raw source of a page, before anything else touches it, and can make arbitrary changes. The function is passed named parameters "page", -"destpage", and "content". It should return the filtered content. +"destpage", "content" and "fullpage". "fullpage" is a true value if, +and only if, a full page's content is being filtered, e.g. as opposed +to a directive parameter. It should return the filtered content. ### preprocess -- cgit v1.2.3 From b225fdc44d4b3d2853db622d59aed7b59788aeec Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 29 Jun 2010 15:45:34 +0200 Subject: po: added a needstranslation() pagespec --- IkiWiki/Plugin/po.pm | 15 +++++++++++++++ doc/ikiwiki/pagespec/po.mdwn | 2 ++ 2 files changed, 17 insertions(+) (limited to 'doc') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 93cf6bbdf..552b6b51b 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -1291,4 +1291,19 @@ sub match_currentlang ($$;@) { } } +sub match_needstranslation ($$;@) { + my $page=shift; + + my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page); + if ($percenttranslated eq 'N/A') { + return IkiWiki::FailReason->new("file is not a translation page"); + } + elsif ($percenttranslated < 100) { + return IkiWiki::SuccessReason->new("file has $percenttranslated translated"); + } + else { + return IkiWiki::FailReason->new("file is fully translated"); + } +} + 1 diff --git a/doc/ikiwiki/pagespec/po.mdwn b/doc/ikiwiki/pagespec/po.mdwn index 40ed9efb6..f8b398575 100644 --- a/doc/ikiwiki/pagespec/po.mdwn +++ b/doc/ikiwiki/pagespec/po.mdwn @@ -11,6 +11,8 @@ wiki: specified as a ISO639-1 (two-letter) language code. * "`currentlang()`" - tests whether a page is written in the same language as the current page. +* "`needstranslation()`" - tests whether a page needs translation + work. Only slave pages match this PageSpec. Note that every non-po page is considered to be written in `po_master_language`, as specified in `ikiwiki.setup`. -- cgit v1.2.3 From 4a1cb092baabda6182fd291dfc9810f6c8efb17e Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 11 Jul 2010 11:00:43 +0200 Subject: Revert po vs. template kludges. This reverts commits dcd57dd5c9f3265bb7a78a5696b90976698c43aa, d4136aea8aa8968d2cd87b40e8d85301a3549323 and d877b9644bcfbbfc5eaf3f7fc13cb96ecda946c9. --- IkiWiki.pm | 6 ++---- IkiWiki/Plugin/editpage.pm | 2 +- IkiWiki/Plugin/inline.pm | 4 ++-- IkiWiki/Plugin/po.pm | 6 ------ IkiWiki/Plugin/sidebar.pm | 2 +- IkiWiki/Render.pm | 4 ++-- doc/plugins/write.mdwn | 4 +--- 7 files changed, 9 insertions(+), 19 deletions(-) (limited to 'doc') diff --git a/IkiWiki.pm b/IkiWiki.pm index f9a30a202..cd9c40795 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1403,16 +1403,14 @@ sub preprocess ($$$;$$) { return $content; } -sub filter ($$$;$) { +sub filter ($$$) { my $page=shift; my $destpage=shift; my $content=shift; - my $fullpage=shift; - $fullpage = 0 unless defined $fullpage; run_hooks(filter => sub { $content=shift->(page => $page, destpage => $destpage, - content => $content, fullpage => $fullpage); + content => $content); }); return $content; diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index 706630203..1a04a72b5 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -187,7 +187,7 @@ sub cgi_editpage ($$) { my $preview=htmlize($page, $page, $type, linkify($page, $page, preprocess($page, $page, - filter($page, $page, $content, 'fullpage'), 0, 1))); + filter($page, $page, $content), 0, 1))); run_hooks(format => sub { $preview=shift->( page => $page, diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm index a04dd6630..715a3d652 100644 --- a/IkiWiki/Plugin/inline.pm +++ b/IkiWiki/Plugin/inline.pm @@ -403,7 +403,7 @@ sub preprocess_inline (@) { linkify($page, $params{destpage}, preprocess($page, $params{destpage}, filter($page, $params{destpage}, - readfile(srcfile($file)), 'fullpage'))); + readfile(srcfile($file))))); } else { $ret.="\n". @@ -474,7 +474,7 @@ sub get_inline_content ($$) { linkify($page, $destpage, preprocess($page, $destpage, filter($page, $destpage, - readfile(srcfile($file)), 'fullpage')))); + readfile(srcfile($file)))))); $nested--; if (isinternal($page)) { # make inlined text of internal pages searchable diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index cadc13ba1..ecfbb6f78 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -259,12 +259,6 @@ sub filter (@) { my $page = $params{page}; my $destpage = $params{destpage}; my $content = $params{content}; - my $fullpage = $params{fullpage}; - - unless ($fullpage) { - return $content; - } - if (istranslation($page) && ! alreadyfiltered($page, $destpage)) { $content = po_to_markup($page, $content); setalreadyfiltered($page, $destpage); diff --git a/IkiWiki/Plugin/sidebar.pm b/IkiWiki/Plugin/sidebar.pm index 100015cee..2d495db2c 100644 --- a/IkiWiki/Plugin/sidebar.pm +++ b/IkiWiki/Plugin/sidebar.pm @@ -89,7 +89,7 @@ sub sidebar_content ($) { return IkiWiki::htmlize($sidebar_page, $page, $sidebar_type, IkiWiki::linkify($sidebar_page, $page, IkiWiki::preprocess($sidebar_page, $page, - IkiWiki::filter($sidebar_page, $page, $content, 'fullpage')))); + IkiWiki::filter($sidebar_page, $page, $content)))); } } diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index 233d093ed..a653ab2da 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -232,7 +232,7 @@ sub render ($$) { linkify($page, $page, preprocess($page, $page, filter($page, $page, - readfile($srcfile), 'fullpage')))); + readfile($srcfile))))); my $output=htmlpage($page); writefile($output, $config{destdir}, genpage($page, $content)); @@ -837,7 +837,7 @@ sub commandline_render () { my $content=readfile($srcfile); my $page=pagename($file); $pagesources{$page}=$file; - $content=filter($page, $page, $content, 'fullpage'); + $content=filter($page, $page, $content); $content=preprocess($page, $page, $content); $content=linkify($page, $page, $content); $content=htmlize($page, $page, $type, $content); diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 8071f323e..bb8012342 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -200,9 +200,7 @@ value is ignored. Runs on the raw source of a page, before anything else touches it, and can make arbitrary changes. The function is passed named parameters "page", -"destpage", "content" and "fullpage". "fullpage" is a true value if, -and only if, a full page's content is being filtered, e.g. as opposed -to a directive parameter. It should return the filtered content. +"destpage", and "content". It should return the filtered content. ### preprocess -- cgit v1.2.3 From 98cc9460ac67fee606437712882cfa1e5d259729 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 11 Jul 2010 11:58:09 +0200 Subject: po: added an optional target percentage to needstranslation --- IkiWiki/Plugin/po.pm | 17 +++++++++++++++-- doc/ikiwiki/pagespec/po.mdwn | 5 ++++- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'doc') diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ecfbb6f78..9cb047992 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -1287,16 +1287,29 @@ sub match_currentlang ($$;@) { sub match_needstranslation ($$;@) { my $page=shift; + my $wanted=shift; + + if (defined $wanted && $wanted ne "") { + if ($wanted !~ /^\d+$/) { + return IkiWiki::FailReason->new("parameter is not an integer"); + } + elsif ($wanted > 100) { + return IkiWiki::FailReason->new("parameter is greater than 100"); + } + } + else { + $wanted=100; + } my $percenttranslated=IkiWiki::Plugin::po::percenttranslated($page); if ($percenttranslated eq 'N/A') { return IkiWiki::FailReason->new("file is not a translatable page"); } - elsif ($percenttranslated < 100) { + elsif ($percenttranslated < $wanted) { return IkiWiki::SuccessReason->new("file has $percenttranslated translated"); } else { - return IkiWiki::FailReason->new("file is fully translated"); + return IkiWiki::FailReason->new("file is translated enough"); } } diff --git a/doc/ikiwiki/pagespec/po.mdwn b/doc/ikiwiki/pagespec/po.mdwn index f8b398575..f9956404c 100644 --- a/doc/ikiwiki/pagespec/po.mdwn +++ b/doc/ikiwiki/pagespec/po.mdwn @@ -12,7 +12,10 @@ wiki: * "`currentlang()`" - tests whether a page is written in the same language as the current page. * "`needstranslation()`" - tests whether a page needs translation - work. Only slave pages match this PageSpec. + work. Only slave pages match this PageSpec. A minimum target + translation percentage can optionally be passed as an integer + parameter: "`needstranslation(50)`" matches only pages less than 50% + translated. Note that every non-po page is considered to be written in `po_master_language`, as specified in `ikiwiki.setup`. -- cgit v1.2.3