From c923e0ba3377f85107ccea1933a042aaec675c77 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 11 Feb 2010 20:39:10 -0500 Subject: Allow globs to be used in user() pagespecs. --- doc/ikiwiki/pagespec.mdwn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'doc/ikiwiki/pagespec.mdwn') diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn index 5f0f44e2e..8d8b1a507 100644 --- a/doc/ikiwiki/pagespec.mdwn +++ b/doc/ikiwiki/pagespec.mdwn @@ -44,7 +44,8 @@ Some more elaborate limits can be added to what matches using these functions: metadata, matching the specified glob. * "`user(username)`" - tests whether a modification is being made by a user with the specified username. If openid is enabled, an openid can also - be put here. + be put here. Glob patterns can be used in the username. For example, + to match all openid users, use `user(*://.*)` * "`admin()`" - tests whether a modification is being made by one of the wiki admins. * "`ip(address)`" - tests whether a modification is being made from the -- cgit v1.2.3 From e091fab0e742c3e3f9029c86d47c858e286becf3 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 11 Feb 2010 22:42:10 -0500 Subject: fix openid pagespec example --- doc/ikiwiki/pagespec.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/ikiwiki/pagespec.mdwn') diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn index 8d8b1a507..5c191f23f 100644 --- a/doc/ikiwiki/pagespec.mdwn +++ b/doc/ikiwiki/pagespec.mdwn @@ -45,7 +45,7 @@ Some more elaborate limits can be added to what matches using these functions: * "`user(username)`" - tests whether a modification is being made by a user with the specified username. If openid is enabled, an openid can also be put here. Glob patterns can be used in the username. For example, - to match all openid users, use `user(*://.*)` + to match all openid users, use `user(*://*)` * "`admin()`" - tests whether a modification is being made by one of the wiki admins. * "`ip(address)`" - tests whether a modification is being made from the -- cgit v1.2.3 From 06d5a19370e07d39e3dcbd975fe479388104b0a5 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 26 Apr 2010 13:47:40 -0400 Subject: document match_guid --- doc/ikiwiki/pagespec.mdwn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'doc/ikiwiki/pagespec.mdwn') diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn index 5c191f23f..7810e790b 100644 --- a/doc/ikiwiki/pagespec.mdwn +++ b/doc/ikiwiki/pagespec.mdwn @@ -40,8 +40,8 @@ Some more elaborate limits can be added to what matches using these functions: * "`internal(glob)`" - like `glob()`, but matches even internal-use pages that globs do not usually match. * "`title(glob)`", "`author(glob)`", "`authorurl(glob)`", - "`license(glob)`", "`copyright(glob)`" - match pages that have the given - metadata, matching the specified glob. + "`license(glob)`", "`copyright(glob)`", "`guid(glob)`" + - match pages that have the given metadata, matching the specified glob. * "`user(username)`" - tests whether a modification is being made by a user with the specified username. If openid is enabled, an openid can also be put here. Glob patterns can be used in the username. For example, -- cgit v1.2.3 From 3ac2ae1f14952bd92038183d92b1eb618c9d0f55 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 26 Apr 2010 18:47:17 -0400 Subject: Add page() PageSpec, which is like glob() but matches only pages, not other files. --- IkiWiki.pm | 10 +++++++++- debian/changelog | 2 ++ doc/ikiwiki/pagespec.mdwn | 11 ++++++----- t/pagespec_match.t | 16 +++++++++++++++- 4 files changed, 32 insertions(+), 7 deletions(-) (limited to 'doc/ikiwiki/pagespec.mdwn') diff --git a/IkiWiki.pm b/IkiWiki.pm index 944001d9b..623396c9c 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2299,7 +2299,11 @@ sub match_glob ($$;@) { my $regexp=IkiWiki::glob2re($glob); if ($page=~/^$regexp$/i) { - if (! IkiWiki::isinternal($page) || $params{internal}) { + if ($params{onlypage} && + ! defined IkiWiki::pagetype($IkiWiki::pagesources{$page})) { + return IkiWiki::FailReason->new("$page is not a page"); + } + elsif (! IkiWiki::isinternal($page) || $params{internal}) { return IkiWiki::SuccessReason->new("$glob matches $page"); } else { @@ -2315,6 +2319,10 @@ sub match_internal ($$;@) { return match_glob($_[0], $_[1], @_, internal => 1) } +sub match_page ($$;@) { + return match_glob($_[0], $_[1], @_, onlypage => 1) +} + sub match_link ($$;@) { my $page=shift; my $link=lc(shift); diff --git a/debian/changelog b/debian/changelog index 1229b1198..610d0c9cb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -75,6 +75,8 @@ ikiwiki (3.20100424) UNRELEASED; urgency=low the top of the web root. This is another things that requires a wiki rebuild on upgrade to this version. * Fix removal of rendered files in rebuild mode. + * Add page() PageSpec, which is like glob() but matches only pages, + not other files. -- Joey Hess Sun, 04 Apr 2010 12:17:11 -0400 diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn index 7810e790b..1c99aefac 100644 --- a/doc/ikiwiki/pagespec.mdwn +++ b/doc/ikiwiki/pagespec.mdwn @@ -24,19 +24,20 @@ match all pages except for Discussion pages and the SandBox: Some more elaborate limits can be added to what matches using these functions: +* "`glob(someglob)`" - matches pages and other files that match the given glob. + Just writing the glob by itself is actually a shorthand for this function. +* "`page(glob)`" - like `glob()`, but only matches pages, not other files * "`link(page)`" - matches only pages that link to a given page (or glob) * "`tagged(tag)`" - matches pages that are tagged or link to the given tag (or tags matched by a glob) * "`backlink(page)`" - matches only pages that a given page links to -* "`creation_month(month)`" - matches only pages created on the given month +* "`creation_month(month)`" - matches only files created on the given month * "`creation_day(mday)`" - or day of the month * "`creation_year(year)`" - or year -* "`created_after(page)`" - matches only pages created after the given page +* "`created_after(page)`" - matches only files created after the given page was created -* "`created_before(page)`" - matches only pages created before the given page +* "`created_before(page)`" - matches only files created before the given page was created -* "`glob(someglob)`" - matches pages that match the given glob. Just writing - the glob by itself is actually a shorthand for this function. * "`internal(glob)`" - like `glob()`, but matches even internal-use pages that globs do not usually match. * "`title(glob)`", "`author(glob)`", "`authorurl(glob)`", diff --git a/t/pagespec_match.t b/t/pagespec_match.t index ade9bca5a..97bcc969c 100755 --- a/t/pagespec_match.t +++ b/t/pagespec_match.t @@ -1,7 +1,7 @@ #!/usr/bin/perl use warnings; use strict; -use Test::More tests => 75; +use Test::More tests => 85; BEGIN { use_ok("IkiWiki"); } @@ -66,7 +66,21 @@ $links{"ook"}=[qw{/blog/tags/foo}]; foreach my $p (keys %links) { $pagesources{$p}="$p.mdwn"; } +$pagesources{"foo.png"}="foo.png"; +$pagesources{"foo"}="foo.mdwn"; +$IkiWiki::hooks{htmlize}{mdwn}={}; +ok(pagespec_match("foo", "foo"), "simple"); +ok(! pagespec_match("foo", "bar"), "simple fail"); +ok(pagespec_match("foo", "foo"), "simple glob"); +ok(pagespec_match("foo", "f*"), "simple glob fail"); +ok(pagespec_match("foo", "page(foo)"), "page()"); +print pagespec_match("foo", "page(foo)")."\n"; +ok(! pagespec_match("foo", "page(bar)"), "page() fail"); +ok(! pagespec_match("foo.png", "page(foo.png)"), "page() fails on non-page"); +ok(! pagespec_match("foo.png", "page(foo*)"), "page() fails on non-page glob"); +ok(pagespec_match("foo", "page(foo)"), "page() glob"); +ok(pagespec_match("foo", "page(f*)"), "page() glob fail"); ok(pagespec_match("foo", "link(bar)"), "link"); ok(pagespec_match("foo", "link(ba?)"), "glob link"); ok(! pagespec_match("foo", "link(quux)"), "failed link"); -- cgit v1.2.3 From d9d910f6765de6ba07508ab56a5a0f93edb4c8ad Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 6 May 2010 19:19:51 -0400 Subject: moved comments pending moderation * 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. --- IkiWiki.pm | 4 +- IkiWiki/Plugin/comments.pm | 130 +++++++++++++++++++++++++++++++------------- debian/NEWS | 6 ++ debian/changelog | 8 +++ doc/ikiwiki/pagespec.mdwn | 2 + doc/plugins/comments.mdwn | 4 +- doc/tips/comments_feed.mdwn | 9 ++- ikiwiki.spec | 2 +- 8 files changed, 121 insertions(+), 44 deletions(-) (limited to 'doc/ikiwiki/pagespec.mdwn') diff --git a/IkiWiki.pm b/IkiWiki.pm index 43995fc96..11cfcdfd2 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -2342,12 +2342,12 @@ sub match_glob ($$;@) { } sub match_internal ($$;@) { - return match_glob($_[0], $_[1], @_, internal => 1) + return match_glob(shift, shift, @_, internal => 1) } sub match_page ($$;@) { my $page=shift; - my $match=match_glob($page, $_[1], @_); + my $match=match_glob($page, shift, @_); if ($match && ! defined IkiWiki::pagetype($IkiWiki::pagesources{$page})) { return IkiWiki::FailReason->new("$page is not a page"); } diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 89560c88b..448ef02f7 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("comment pending %s"), + ''. + gettext("moderation").''); +} + # FIXME: copied verbatim from meta sub safeurl ($) { my $url=shift; @@ -462,9 +473,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}); + 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")), "

". @@ -540,21 +557,24 @@ sub commentmoderation ($$) { my %vars=$cgi->Vars; my $added=0; foreach my $id (keys %vars) { - if ($id =~ /(.*)\Q._comment\E$/) { + if ($id =~ /(.*)\Q._comment(?:_pending)?\E$/) { 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) }; @@ -567,9 +587,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); } @@ -596,15 +613,14 @@ 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(); my $template=template("commentmoderation.tmpl"); @@ -635,26 +651,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; } @@ -689,7 +714,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); @@ -719,7 +744,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', @@ -847,7 +872,8 @@ sub unique_comment_location ($$$) { do { $i++; $location = "$page/$config{comments_pagename}${i}_${content_md5}"; - } while (-e "$dir/$location._comment"); + } while (-e "$dir/$location._comment" || + -e "$dir/$location._comment_pending"); return $location; } @@ -873,7 +899,35 @@ 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; + + my $match=match_glob($page, "$glob/*", @_); + if ($match) { + my $type=IkiWiki::pagetype($IkiWiki::pagesources{$page}); + if ($type ne "_comment") { + return IkiWiki::FailReason->new("$page is not a comment"); + } + } + return $match; +} + +sub match_comment_pending ($$;@) { + my $page = shift; + my $glob = shift; + + my $match=match_glob($page, "$glob/*", @_); + if ($match) { + my $type=IkiWiki::pagetype($IkiWiki::pagesources{$page}); + if ($type ne "_comment_pending") { + return IkiWiki::FailReason->new("$page is not a pending comment"); + } + } + return $match; } 1 diff --git a/debian/NEWS b/debian/NEWS index 4e0c7810b..b751f1478 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -1,5 +1,11 @@ ikiwiki (3.20100505) UNRELEASED; urgency=low + 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 is a significant change to the page.tmpl template in this version. If you have locally modified versions of that template, you will need to update it to contain the following in the HTML : diff --git a/debian/changelog b/debian/changelog index 6b4ba7592..5b51a74f9 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 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. -- Joey Hess Wed, 05 May 2010 18:07:29 -0400 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/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 -- cgit v1.2.3