From: Joey Hess Date: Tue, 19 May 2009 17:07:47 +0000 (-0400) Subject: Merge branch 'master' into po X-Git-Tag: 3.15~188 X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/commitdiff_plain/ef003f48f4a3fe8fb67fda62c70a299b07d75976?ds=sidebyside;hp=-c Merge branch 'master' into po Conflicts: debian/changelog --- ef003f48f4a3fe8fb67fda62c70a299b07d75976 diff --combined IkiWiki.pm index d0cfb2d57,061a1c6db..0e59b1b55 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@@ -18,15 -18,15 +18,15 @@@ use vars qw{%config %links %oldlinks %p use Exporter q{import}; our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match - bestlink htmllink readfile writefile pagetype srcfile pagename - displaytime will_render gettext urlto targetpage - add_underlay pagetitle titlepage linkpage newpagefile - inject + pagespec_match_list bestlink htmllink readfile writefile + pagetype srcfile pagename displaytime will_render gettext urlto + targetpage add_underlay pagetitle titlepage linkpage + newpagefile inject add_link %config %links %pagestate %wikistate %renderedfiles %pagesources %destsources); our $VERSION = 3.00; # plugin interface version, next is ikiwiki version our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE - our $installdir=''; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE + our $installdir='/usr'; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE # Optimisation. use Memoize; @@@ -157,6 -157,13 +157,13 @@@ sub getsetup () safe => 0, # path rebuild => 0, }, + underlaydirbase => { + type => "internal", + default => "$installdir/share/ikiwiki", + description => "parent directory containing additional underlays", + safe => 0, + rebuild => 0, + }, wrappers => { type => "internal", default => [], @@@ -715,7 -722,7 +722,7 @@@ sub add_underlay ($) my $dir=shift; if ($dir !~ /^\//) { - $dir="$config{underlaydir}/../$dir"; + $dir="$config{underlaydirbase}/$dir"; } if (! grep { $_ eq $dir } @{$config{underlaydirs}}) { @@@ -1339,7 -1346,7 +1346,7 @@@ sub check_content (@) foreach my $line (split("\n", $params{content})) { push @diff, $line if ! exists $old{$_}; } - $params{content}=join("\n", @diff); + $params{diff}=join("\n", @diff); } my $ok; @@@ -1671,12 -1678,6 +1678,6 @@@ sub rcs_receive () $hooks{rcs}{rcs_receive}{call}->(); } - sub safequote ($) { - my $s=shift; - $s=~s/[{}]//g; - return "q{$s}"; - } - sub add_depends ($$) { my $page=shift; my $pagespec=shift; @@@ -1757,6 -1758,14 +1758,14 @@@ sub inject use warnings; } + sub add_link ($$) { + my $page=shift; + my $link=shift; + + push @{$links{$page}}, $link + unless grep { $_ eq $link } @{$links{$page}}; + } + sub pagespec_merge ($$) { my $a=shift; my $b=shift; @@@ -1770,6 -1779,7 +1779,7 @@@ sub pagespec_translate ($) # Convert spec to perl code. my $code=""; + my @data; while ($spec=~m{ \s* # ignore whitespace ( # 1: match a single word @@@ -1797,14 -1807,17 +1807,17 @@@ } elsif ($word =~ /^(\w+)\((.*)\)$/) { if (exists $IkiWiki::PageSpec::{"match_$1"}) { - $code.="IkiWiki::PageSpec::match_$1(\$page, ".safequote($2).", \@_)"; + push @data, $2; + $code.="IkiWiki::PageSpec::match_$1(\$page, \$data[$#data], \@_)"; } else { - $code.="IkiWiki::FailReason->new(".safequote(qq{unknown function in pagespec "$word"}).")"; + push @data, qq{unknown function in pagespec "$word"}; + $code.="IkiWiki::ErrorReason->new(\$data[$#data])"; } } else { - $code.=" IkiWiki::PageSpec::match_glob(\$page, ".safequote($word).", \@_)"; + push @data, $word; + $code.=" IkiWiki::PageSpec::match_glob(\$page, \$data[$#data], \@_)"; } } @@@ -1827,11 -1840,35 +1840,35 @@@ sub pagespec_match ($$;@) } my $sub=pagespec_translate($spec); - return IkiWiki::FailReason->new("syntax error in pagespec \"$spec\"") + return IkiWiki::ErrorReason->new("syntax error in pagespec \"$spec\"") if $@ || ! defined $sub; return $sub->($page, @params); } + sub pagespec_match_list ($$;@) { + my $pages=shift; + my $spec=shift; + my @params=@_; + + my $sub=pagespec_translate($spec); + error "syntax error in pagespec \"$spec\"" + if $@ || ! defined $sub; + + my @ret; + my $r; + foreach my $page (@$pages) { + $r=$sub->($page, @params); + push @ret, $page if $r; + } + + if (! @ret && defined $r && $r->isa("IkiWiki::ErrorReason")) { + error(sprintf(gettext("cannot match pages: %s"), $r)); + } + else { + return @ret; + } + } + sub pagespec_valid ($) { my $spec=shift; @@@ -1861,6 -1898,10 +1898,10 @@@ sub new return bless \$value, $class; } + package IkiWiki::ErrorReason; + + our @ISA = 'IkiWiki::FailReason'; + package IkiWiki::SuccessReason; use overload ( @@@ -2021,7 -2062,7 +2062,7 @@@ sub match_user ($$;@) my %params=@_; if (! exists $params{user}) { - return IkiWiki::FailReason->new("no user specified"); + return IkiWiki::ErrorReason->new("no user specified"); } if (defined $params{user} && lc $params{user} eq lc $user) { @@@ -2041,7 -2082,7 +2082,7 @@@ sub match_admin ($$;@) my %params=@_; if (! exists $params{user}) { - return IkiWiki::FailReason->new("no user specified"); + return IkiWiki::ErrorReason->new("no user specified"); } if (defined $params{user} && IkiWiki::is_admin($params{user})) { @@@ -2061,7 -2102,7 +2102,7 @@@ sub match_ip ($$;@) my %params=@_; if (! exists $params{ip}) { - return IkiWiki::FailReason->new("no IP specified"); + return IkiWiki::ErrorReason->new("no IP specified"); } if (defined $params{ip} && lc $params{ip} eq lc $ip) { diff --combined IkiWiki/Plugin/blogspam.pm index 58303418f,da63d3edb..626c8ec42 --- a/IkiWiki/Plugin/blogspam.pm +++ b/IkiWiki/Plugin/blogspam.pm @@@ -9,6 -9,7 +9,7 @@@ my $defaulturl='http://test.blogspam.ne sub import { hook(type => "getsetup", id => "blogspam", call => \&getsetup); + hook(type => "checkconfig", id => "blogspam", call => \&checkconfig); hook(type => "checkcontent", id => "blogspam", call => \&checkcontent); } @@@ -43,17 -44,19 +44,19 @@@ sub getsetup () }, } - sub checkcontent (@) { - my %params=@_; - + sub checkconfig () { + # This is done at checkconfig time because printing an error + # if the module is missing when a spam is posted would not + # let the admin know about the problem. eval q{ use RPC::XML; use RPC::XML::Client; }; - if ($@) { - warn($@); - return undef; - } + error $@ if $@; + } + + sub checkcontent (@) { + my %params=@_; if (exists $config{blogspam_pagespec}) { return undef @@@ -85,7 -88,7 +88,7 @@@ my %req=( ip => $ENV{REMOTE_ADDR}, - comment => $params{content}, + comment => defined $params{diff} ? $params{diff} : $params{content}, subject => defined $params{subject} ? $params{subject} : "", name => defined $params{author} ? $params{author} : "", link => exists $params{url} ? $params{url} : "", diff --combined debian/changelog index f7d336de2,7efa31cf1..c684565c5 --- a/debian/changelog +++ b/debian/changelog @@@ -1,12 -1,59 +1,68 @@@ - ikiwiki (3.11) unstable; urgency=low ++ikiwiki (3.14) UNRELEASED; urgency=low + + * Add new hooks: canremove, canrename, rename. (intrigeri) + * rename: Refactor subpage rename handling code into rename hook. (intrigeri) + * po: New plugin, suporting translation of wiki pages using po files. + (intrigeri) + + -- Joey Hess Mon, 20 Apr 2009 19:40:25 -0400 + + ikiwiki (3.13) UNRELEASED; urgency=low + + * ikiwiki-transition: If passed a nonexistant srcdir, or one not + containing .ikiwiki, abort with an error rather than creating it. + * Allow underlaydir to be overridden without messing up inclusion + of other underlays via add_underlay. + * More friendly display of markdown, textile in edit form selector + (jmtd) + * Allow curly braces to be used in pagespecs, and avoid a whole class + of potential security problems, by avoiding performing any string + interpolation on user-supplied data when translating pagespecs. + + -- Joey Hess Wed, 06 May 2009 20:45:44 -0400 + + ikiwiki (3.12) unstable; urgency=low + + * Re-enable python-support and add python:Depends to control file. + * ikiwiki-makerepo: Avoid using abs_path, as it apparently + fails on nonexistant directories with some broken perl + versions. + * inline: Minor optimisation. + * add_link: New function, which plugins should use rather than + modifying %links directly, to avoid it accumulating duplicates. + * ikiwiki-transition: Add a deduplinks action, that can be used + to remove duplicate links and optimise a wiki w/o rebuilding it. + * external: Fix pagespec_match and pagespec_match_list. + Closes: #527281 + + -- Joey Hess Wed, 06 May 2009 00:31:16 -0400 + + ikiwiki (3.11) unstable; urgency=low + + * Avoid using python-support. Closes: #525086 + * websetup: Display stderr in browser if ikiwiki setup fails. + * blogspam: Load RPC::XML library in checkconfig, so that an + error can be printed at that point if it's not available, + allowing the admin to see it during wiki setup. + Closes: #520015 + * websetup: If setup fails, restore old setup file. + * relativedate: Deal with clock skew. + * Add IkiWiki::ErrorReason objects, and modify pagespecs to return + them in cases where they fail to match due to a configuration or syntax + error. + * pagespec_match_list: New API function, matches pages in a list + and throws an error if the pagespec is bad. + * inline, brokenlinks, calendar, linkmap, map, orphans, pagecount, + pagestate, postsparkline: Display a handy error message if the pagespec + is erronious. + * comments: Add link to comment post form to allow user to sign in + if they wish to, if the configuration makes signin optional + for commenting. + * Updated Danish translation from Jonas Smedegaard. Closes: #525751 + * translation.mdwn: Typo fixes. Closes: #525753 + + -- Joey Hess Mon, 04 May 2009 15:45:10 -0400 + ikiwiki (3.10) unstable; urgency=low * darcs: Finally added support for this VCS, thanks to many diff --combined debian/control index 8e7806de3,57c5f917a..05ccd0df3 --- a/debian/control +++ b/debian/control @@@ -9,14 -9,14 +9,14 @@@ Build-Depends-Indep: dpkg-dev (>= 1.9.0 libhtml-parser-perl, liburi-perl, perlmagick Maintainer: Joey Hess Uploaders: Josh Triplett - Standards-Version: 3.8.0 + Standards-Version: 3.8.1 Homepage: http://ikiwiki.info/ Vcs-Git: git://git.ikiwiki.info/ Vcs-Browser: http://git.ikiwiki.info/?p=ikiwiki Package: ikiwiki Architecture: all - Depends: ${misc:Depends}, ${perl:Depends}, + Depends: ${misc:Depends}, ${perl:Depends}, ${python:Depends}, libtext-markdown-perl | markdown, libhtml-scrubber-perl, libhtml-template-perl, libhtml-parser-perl, liburi-perl @@@ -35,7 -35,7 +35,7 @@@ Suggests: viewvc | gitweb | viewcvs, li liblocale-gettext-perl (>= 1.05-1), libtext-typography-perl, libtext-csv-perl, libdigest-sha1-perl, graphviz, libnet-amazon-s3-perl, sparkline-php, texlive, dvipng, libtext-wikicreole-perl, - libsort-naturally-perl, libtext-textile-perl + libsort-naturally-perl, libtext-textile-perl, po4a (>= 0.35-1), gettext Conflicts: ikiwiki-plugin-table Replaces: ikiwiki-plugin-table Provides: ikiwiki-plugin-table diff --combined doc/plugins/write.mdwn index cccfb9bba,d0f6a09e1..ac0935773 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@@ -98,7 -98,7 +98,7 @@@ function is passed no values This allows a plugin to manipulate the list of files that need to be built when the wiki is refreshed. The function is passed a reference to an - array of pages that will be rebuilt, and can modify the array, either + array of files that will be rebuilt, and can modify the array, either adding or removing files from it. ### scan @@@ -107,8 -107,8 +107,8 @@@ This hook is called early in the process of building the wiki, and is used as a first pass scan of the page, to collect metadata about the page. It's - mostly used to scan the page for [[WikiLinks|ikiwiki/WikiLink]], and add them to `%links`. - Present in IkiWiki 2.40 and later. + mostly used to scan the page for [[WikiLinks|ikiwiki/WikiLink]], and add + them to `%links`. Present in IkiWiki 2.40 and later. The function is passed named parameters "page" and "content". Its return value is ignored. @@@ -151,11 -151,11 +151,11 @@@ parameter is set to a true value if th If `hook` is passed an optional "scan" parameter, set to a true value, this makes the hook be called during the preliminary scan that ikiwiki makes of updated pages, before begining to render pages. This should be done if the - hook modifies data in `%links`. Note that doing so will make the hook be - run twice per page build, so avoid doing it for expensive hooks. (As an - optimisation, if your preprocessor hook is called in a void context, you - can assume it's being run in scan mode, and avoid doing expensive things at - that point.) + hook modifies data in `%links` (typically by calling `add_link`). Note that + doing so will make the hook be run twice per page build, so avoid doing it + for expensive hooks. (As an optimisation, if your preprocessor hook is + called in a void context, you can assume it's being run in scan mode, and + avoid doing expensive things at that point.) Note that if the [[htmlscrubber]] is enabled, html in preprocessor [[ikiwiki/directive]] output is sanitised, which may limit what @@@ -174,7 -174,8 +174,8 @@@ links. The function is passed named par and later. Plugins that implement linkify must also implement a scan hook, that scans - for the links on the page and adds them to `%links`. + for the links on the page and adds them to `%links` (typically by calling + `add_link`). ### htmlize @@@ -197,6 -198,9 +198,9 @@@ value, then the id parameter specifies a whole filename that can be htmlized. This is useful for files like `Makefile` that have no extension. + If `hook` is passed an optional "longname" parameter, this value is used + when prompting a user to choose a page type on the edit page form. + ### pagetemplate hook(type => "pagetemplate", id => "foo", call => \&pagetemplate); @@@ -326,26 -330,6 +330,26 @@@ This hook should avoid directly redirec since it's sometimes used to test to see which pages in a set of pages a user can edit. +### canremove + + hook(type => "canremove", id => "foo", call => \&canremove); + +This hook can be used to implement arbitrary access methods to control +when a page can be removed using the web interface (commits from +revision control bypass it). It works exactly like the `canedit` hook, +but is passed the named parameters `cgi` (a CGI object), `session` +(a session object) and `page` (the page subject to deletion). + +### canrename + + hook(type => "canrename", id => "foo", call => \&canrename); + +This hook can be used to implement arbitrary access methods to control when +a page can be renamed using the web interface (commits from revision control +bypass it). It works exactly like the `canedit` hook, +but is passed the named parameters `cgi` (a CGI object), `session` (a +session object), `src`, `srcfile`, `dest` and `destfile`. + ### checkcontent hook(type => "checkcontent", id => "foo", call => \&checkcontent); @@@ -358,9 -342,8 +362,9 @@@ the content the user has entered is a c additional parameters: `author`, `url`, and `subject`. The `subject` parameter may also be filled with the user's comment about the change. -Note: When the user edits an existing wiki page, the passed `content` will -include only the lines that they added to the page, or modified. +Note: When the user edits an existing wiki page, this hook is also +passed a `diff` named parameter, which will include only the lines +that they added to the page, or modified. The hook should return `undef` on success. If the content is disallowed, it should return a message stating what the problem is, or a function @@@ -411,28 -394,9 +415,28 @@@ they're saved, etc hook(type => "renamepage", id => "foo", call => \&renamepage); This hook is called by the [[plugins/rename]] plugin when it renames -something. The hook is passed named parameters: `page`, `oldpage`, -`newpage`, and `content`, and should try to modify the content to reflect -the name change. For example, by converting links to point to the new page. +something, once per page linking to the renamed page's old location. +The hook is passed named parameters: `page`, `oldpage`, `newpage`, and +`content`, and should try to modify the content of `page` to reflect +the name change. For example, by converting links to point to the +new page. + +### rename + + hook(type => "rename", id => "foo", call => \&rename); + +When a page or set of pages is renamed, the referenced function is +called for every page, and is passed named parameters: + +* `torename`: a reference to a hash with keys: `src`, `srcfile`, + `dest`, `destfile`, `required`. +* `cgi`: a CGI object +* `session`: a session object. + +Such a hook function returns any additional rename hashes it wants to +add. This hook is applied recursively to returned additional rename +hashes, so that it handles the case where two plugins use the hook: +plugin A would see when plugin B adds a new file to be renamed. ### getsetup @@@ -612,6 -576,19 +616,19 @@@ The most often used is "location", whic PageSpec should match against. If not passed, relative PageSpecs will match relative to the top of the wiki. + #### `pagespec_match_list($$;@)` + + Passed a reference to a list of page names, and [[ikiwiki/PageSpec]], + returns the set of pages that match the [[ikiwiki/PageSpec]]. + + Additional named parameters can be passed, to further limit the match. + The most often used is "location", which specifies the location the + PageSpec should match against. If not passed, relative PageSpecs will match + relative to the top of the wiki. + + Unlike pagespec_match, this may throw an error if there is an error in + the pagespec. + #### `bestlink($$)` Given a page and the text of a link on the page, determine which @@@ -780,6 -757,11 +797,11 @@@ Optionally, a third parameter can be pa filename of the page. For example, `targetpage("foo", "rss", "feed")` will yield something like `foo/feed.rss`. + #### `add_link($$)` + + This adds a link to `%links`, ensuring that duplicate links are not + added. Pass it the page that contains the link, and the link text. + ## Miscellaneous ### Internal use pages @@@ -930,9 -912,12 +952,12 @@@ It's also possible to write plugins tha IkiWiki::PageSpec package, that is named `match_foo`, where "foo()" is how it will be accessed in a [[ikiwiki/PageSpec]]. The function will be passed two parameters: The name of the page being matched, and the thing to match - against. It may also be passed additional, named parameters. It should return - a IkiWiki::SuccessReason object if the match succeeds, or an - IkiWiki::FailReason object if the match fails. + against. It may also be passed additional, named parameters. + + It should return a IkiWiki::SuccessReason object if the match succeeds, or + an IkiWiki::FailReason object if the match fails. If the match cannot be + attempted at all, for any page, it can instead return an + IkiWiki::ErrorReason object explaining why. ### Setup plugins