diff options
-rw-r--r-- | IkiWiki/Plugin/comments.pm | 138 | ||||
-rw-r--r-- | IkiWiki/Render.pm | 2 | ||||
-rw-r--r-- | debian/NEWS | 6 | ||||
-rw-r--r-- | debian/changelog | 8 | ||||
-rw-r--r-- | doc/examples/blog/comments.mdwn | 6 | ||||
-rw-r--r-- | doc/ikiwiki/pagespec.mdwn | 2 | ||||
-rw-r--r-- | doc/plugins/comments.mdwn | 4 | ||||
-rw-r--r-- | doc/roadmap.mdwn | 1 | ||||
-rw-r--r-- | doc/tips/comments_feed.mdwn | 9 | ||||
-rw-r--r-- | ikiwiki.spec | 2 |
10 files changed, 130 insertions, 48 deletions
diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 6d513cd2a..3cafcbe9c 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -26,8 +26,11 @@ sub import { hook(type => "preprocess", id => '_comment', call => \&preprocess); hook(type => "sessioncgi", id => 'comment', call => \&sessioncgi); hook(type => "htmlize", id => "_comment", call => \&htmlize); + hook(type => "htmlize", id => "_comment_pending", + call => \&htmlize_pending); hook(type => "pagetemplate", id => "comments", call => \&pagetemplate); - hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup); + hook(type => "formbuilder_setup", id => "comments", + call => \&formbuilder_setup); # Load goto to fix up user page links for logged-in commenters IkiWiki::loadplugin("goto"); IkiWiki::loadplugin("inline"); @@ -104,6 +107,14 @@ sub htmlize { return $params{content}; } +sub htmlize_pending { + my %params = @_; + return sprintf(gettext("this comment needs %s"), + '<a href="'. + IkiWiki::cgiurl(do => "commentmoderation").'">'. + gettext("moderation").'</a>'); +} + # FIXME: copied verbatim from meta sub safeurl ($) { my $url=shift; @@ -466,9 +477,15 @@ sub editcomment ($$) { $postcomment=0; if (! $ok) { - my $penddir=$config{wikistatedir}."/comments_pending"; - $location=unique_comment_location($page, $content, $penddir); - writefile("$location._comment", $penddir, $content); + $location=unique_comment_location($page, $content, $config{srcdir}, "._comment_pending"); + writefile("$location._comment_pending", $config{srcdir}, $content); + + # Refresh so anything that deals with pending + # comments can be updated. + require IkiWiki::Render; + IkiWiki::refresh(); + IkiWiki::saveindex(); + IkiWiki::printheader($session); print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")), "<p>". @@ -544,21 +561,24 @@ sub commentmoderation ($$) { my %vars=$cgi->Vars; my $added=0; foreach my $id (keys %vars) { - if ($id =~ /(.*)\Q._comment\E$/) { + if ($id =~ /(.*)\._comment(?:_pending)?$/) { my $action=$cgi->param($id); next if $action eq 'Defer' && ! $rejectalldefer; # Make sure that the id is of a legal - # pending comment before untainting. - my ($f)= $id =~ /$config{wiki_file_regexp}/; + # pending comment. + my ($f) = $id =~ /$config{wiki_file_regexp}/; if (! defined $f || ! length $f || IkiWiki::file_pruned($f)) { error("illegal file"); } - my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1)); - my $file="$config{wikistatedir}/comments_pending/". - IkiWiki::possibly_foolish_untaint($id); + my $page=IkiWiki::dirname($f); + my $file="$config{srcdir}/$f"; + if (! -e $file) { + # old location + $file="$config{wikistatedir}/comments_pending/".$f; + } if ($action eq 'Accept') { my $content=eval { readfile($file) }; @@ -571,9 +591,6 @@ sub commentmoderation ($$) { $added++; } - # This removes empty subdirs, so the - # .ikiwiki/comments_pending dir will - # go away when all are moderated. require IkiWiki::Render; IkiWiki::prune($file); } @@ -600,16 +617,15 @@ sub commentmoderation ($$) { } my @comments=map { - my ($id, $ctime)=@{$_}; - my $file="$config{wikistatedir}/comments_pending/$id"; - my $content=readfile($file); + my ($id, $dir, $ctime)=@{$_}; + my $content=readfile("$dir/$id"); my $preview=previewcomment($content, $id, - IkiWiki::dirname($_), $ctime); + $id, $ctime); { id => $id, view => $preview, - } - } sort { $b->[1] <=> $a->[1] } comments_pending(); + } + } sort { $b->[2] <=> $a->[2] } comments_pending(); my $template=template("commentmoderation.tmpl"); $template->param( @@ -639,26 +655,35 @@ sub formbuilder_setup (@) { } sub comments_pending () { - my $dir="$config{wikistatedir}/comments_pending/"; - return unless -d $dir; - my @ret; + eval q{use File::Find}; error($@) if $@; - find({ - no_chdir => 1, - wanted => sub { - my $file=decode_utf8($_); - $file=~s/^\Q$dir\E\/?//; - return if ! length $file || IkiWiki::file_pruned($file) - || -l $_ || -d _ || $file !~ /\Q._comment\E$/; - my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint - if (defined $f) { - my $ctime=(stat($_))[10]; - push @ret, [$f, $ctime]; + + my $find_comments=sub { + my $dir=shift; + my $extension=shift; + return unless -d $dir; + find({ + no_chdir => 1, + wanted => sub { + my $file=decode_utf8($_); + $file=~s/^\Q$dir\E\/?//; + return if ! length $file || IkiWiki::file_pruned($file) + || -l $_ || -d _ || $file !~ /\Q$extension\E$/; + my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint + if (defined $f) { + my $ctime=(stat($_))[10]; + push @ret, [$f, $dir, $ctime]; + } } - } - }, $dir); + }, $dir); + }; + + $find_comments->($config{srcdir}, "._comment_pending"); + # old location + $find_comments->("$config{wikistatedir}/comments_pending/", + "._comment"); return @ret; } @@ -693,7 +718,7 @@ sub previewcomment ($$$) { sub commentsshown ($) { my $page=shift; - return ! pagespec_match($page, "internal(*/$config{comments_pagename}*)", + return ! pagespec_match($page, "comment(*)", location => $page) && pagespec_match($page, $config{comments_pagespec}, location => $page); @@ -723,7 +748,7 @@ sub pagetemplate (@) { my $comments = undef; if ($shown) { $comments = IkiWiki::preprocess_inline( - pages => "internal($page/$config{comments_pagename}*)", + pages => "comment($page)", template => 'comment', show => 0, reverse => 'yes', @@ -837,21 +862,20 @@ sub num_comments ($$) { return @comments; } -sub unique_comment_location ($$$) { +sub unique_comment_location ($$$$) { my $page=shift; - eval q{use Digest::MD5 'md5_hex'}; error($@) if $@; my $content_md5=md5_hex(Encode::encode_utf8(shift)); - my $dir=shift; + my $ext=shift || "._comment"; my $location; my $i = num_comments($page, $dir); do { $i++; $location = "$page/$config{comments_pagename}${i}_${content_md5}"; - } while (-e "$dir/$location._comment"); + } while (-e "$dir/$location$ext"); return $location; } @@ -877,7 +901,37 @@ sub match_postcomment ($$;@) { if (! $postcomment) { return IkiWiki::FailReason->new("not posting a comment"); } - return match_glob($page, $glob); + return match_glob($page, $glob, @_); +} + +sub match_comment ($$;@) { + my $page = shift; + my $glob = shift; + + if (! IkiWiki::isinternal($page)) { + return IkiWiki::FailReason->new("$page is not a comment"); + } + my $type=IkiWiki::pagetype($IkiWiki::pagesources{$page}); + if (defined $type && $type ne "_comment") { + return IkiWiki::FailReason->new("$page is not a comment"); + } + + return match_glob($page, "$glob/*", internal => 1, @_); +} + +sub match_comment_pending ($$;@) { + my $page = shift; + my $glob = shift; + + if (! IkiWiki::isinternal($page)) { + return IkiWiki::FailReason->new("$page is not a pending comment"); + } + my $type=IkiWiki::pagetype($IkiWiki::pagesources{$page}); + if (defined $type && $type ne "_comment_pending") { + return IkiWiki::FailReason->new("$page is not a pending comment"); + } + + return match_glob($page, "$glob/*", internal => 1, @_); } 1 diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index c9ba95363..8b1b9aef4 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -641,7 +641,7 @@ sub render_dependent ($$$$$$$) { # only consider internal files # if the page explicitly depends # on such files - my $internal_dep=$dep =~ /internal\(/; + my $internal_dep=$dep =~ /(?:internal|comment|comment_pending)\(/; my $in=sub { my $list=shift; diff --git a/debian/NEWS b/debian/NEWS index e65a15457..68f0a207b 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -8,6 +8,12 @@ ikiwiki (3.20100505) UNRELEASED; urgency=low <TMPL_IF FORCEBASEURL><base href="<TMPL_VAR FORCEBASEURL>" /><TMPL_ELSE> <TMPL_IF BASEURL><base href="<TMPL_VAR BASEURL>" /></TMPL_IF> </TMPL_IF> + + Also, there is a new "comment()" pagespec, that can be used to match a + comment on a page. It is recommended it be used instead of the old + method of using a pagespec such as "internal(comment_*)" to match + things that looked like comments. The old pagespec will now also match + comments that are held for moderation; likely not what you want. There have also been some changes to the style.css in this version, particularly to support the new openid selector. If you have a modified diff --git a/debian/changelog b/debian/changelog index 050613706..f74e9929f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,14 @@ ikiwiki (3.20100505) UNRELEASED; urgency=low a single template, page.tmpl. * If you have a locally customised page.tmpl, it needs to be updated to set <base> when BASEURL or FORCEBAREURL is set. + * comments: Comments pending moderation are now stored in the srcdir + alongside accepted comments, but with a `._comment_pending` extension. + This allows easier byhand moderation, as the "_pending" need + only be stripped off and the comment be committed to version control. + * The `comment_pending()` pagespec can be used to match such unmoderated + comments, which makes it easy to add a feed of them, or a counter + indicating how many there are. + * Belatedly added a `comment()` pagespec. * Gave comment and page editing forms some CSS and accessability love. * Renamed postscan hook to indexhtml, to reflect its changed position, and typical use. diff --git a/doc/examples/blog/comments.mdwn b/doc/examples/blog/comments.mdwn index 0b503ba01..32ffa5537 100644 --- a/doc/examples/blog/comments.mdwn +++ b/doc/examples/blog/comments.mdwn @@ -1,3 +1,7 @@ This page will show recent comments made to posts in the [[blog|index]]. -[[!inline pages="./posts/*/Discussion or internal(./posts/*/comment_*)"]] +There are [[!pagecount pages="comment_pending(/posts/*)"]] comments +in the moderation queue. +[[!inline pages="comment_pending(/posts/*)" name=pendingmoderation show=-1]] + +[[!inline pages="./posts/*/Discussion or comment(./posts/*)"]] diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn index 1c99aefac..c66395f84 100644 --- a/doc/ikiwiki/pagespec.mdwn +++ b/doc/ikiwiki/pagespec.mdwn @@ -51,6 +51,8 @@ Some more elaborate limits can be added to what matches using these functions: wiki admins. * "`ip(address)`" - tests whether a modification is being made from the specified IP address. +* "`comment(glob)`" - matches comments to a page matching the glob. +* "`comment_pending(glob)`" - matches unmoderated, pending comments. * "`postcomment(glob)`" - matches only when comments are being posted to a page matching the specified glob diff --git a/doc/plugins/comments.mdwn b/doc/plugins/comments.mdwn index 775ef75a0..14bd28a04 100644 --- a/doc/plugins/comments.mdwn +++ b/doc/plugins/comments.mdwn @@ -49,5 +49,5 @@ held for moderation. (Or with the [[moderatedcomments]] plugin, all comments will be held.) Wiki admins can access the comment moderation queue via a button on their Preferences page. -The comments are stored in `.ikiwiki/comments_pending/`, and can be -deleted, or moved into the wiki's srcdir to be posted. +The unmoderated comments are stored in the `srcdir` with a filename ending +in "._comment_pending". They are not checked into revision control. diff --git a/doc/roadmap.mdwn b/doc/roadmap.mdwn index e257c21a2..cdec6e7e8 100644 --- a/doc/roadmap.mdwn +++ b/doc/roadmap.mdwn @@ -81,6 +81,7 @@ Probably incomplete list: * Enable tagbase by default (so that tag autocreation will work by default). Note that this is already done for wikis created by `auto-blog.setup`. * [[tips/html5]] on by default (some day..) +* Remove support for old `.ikiwiki/comments_pending` from comment plugin. In general, we try to use [[ikiwiki-transition]] or forced rebuilds on upgrade to deal with changes that break compatability. Some things that diff --git a/doc/tips/comments_feed.mdwn b/doc/tips/comments_feed.mdwn index 6d4dbb803..3d6a8c449 100644 --- a/doc/tips/comments_feed.mdwn +++ b/doc/tips/comments_feed.mdwn @@ -3,8 +3,15 @@ blog can have comments added to them. Pages with comments even have special feeds that can be used to subscribe to those comments. But you'd like to add a feed that contains all the comments posted to any page. Here's how: - \[[!inline pages="internal(*/comment_*)" template=comment]] + \[[!inline pages="comment(*)" template=comment]] The special [[ikiwiki/PageSpec]] matches all comments. The [[template|templates]] causes the comments to be displayed formatted nicely. + +--- + +It's also possible to make a feed of comments that are held pending +moderation. + + \[[!inline pages="comment_pending(*)" template=comment]] diff --git a/ikiwiki.spec b/ikiwiki.spec index 76398e9fb..b2b5af3dc 100644 --- a/ikiwiki.spec +++ b/ikiwiki.spec @@ -1,5 +1,5 @@ Name: ikiwiki -Version: 3.20100504 +Version: 3.20100505 Release: 1%{?dist} Summary: A wiki compiler |