sub import {
hook(type => "checkconfig", id => 'comments', call => \&checkconfig);
hook(type => "getsetup", id => 'comments', call => \&getsetup);
+ hook(type => "preprocess", id => 'comment', call => \&preprocess);
+ # here for backwards compatability with old comments
hook(type => "preprocess", id => '_comment', call => \&preprocess);
hook(type => "sessioncgi", id => 'comment', call => \&sessioncgi);
hook(type => "htmlize", id => "_comment", call => \&htmlize);
hook(type => "pagetemplate", id => "comments", call => \&pagetemplate);
- hook(type => "cgi", id => "comments", call => \&linkcgi);
+ 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");
}
}
else {
$commentauthorurl = IkiWiki::cgiurl(
- do => 'commenter',
+ do => 'goto',
page => (length $config{userdir}
? "$config{userdir}/$commentuser"
: "$commentuser"));
if ($params{page} =~ m/\/(\Q$config{comments_pagename}\E\d+)$/) {
$pagestate{$page}{meta}{permalink} = urlto(IkiWiki::dirname($params{page}), undef, 1).
- "#".$params{page};
+ "#".page_to_id($params{page});
}
eval q{use Date::Parse};
return $content;
}
-# This is exactly the same as recentchanges_link :-(
-sub linkcgi ($) {
- my $cgi=shift;
- if (defined $cgi->param('do') && $cgi->param('do') eq "commenter") {
-
- my $page=decode_utf8($cgi->param("page"));
- if (! defined $page) {
- error("missing page parameter");
- }
-
- IkiWiki::loadindex();
-
- my $link=bestlink("", $page);
- if (! length $link) {
- print "Content-type: text/html\n\n";
- print IkiWiki::misctemplate(gettext(gettext("missing page")),
- "<p>".
- sprintf(gettext("The page %s does not exist."),
- htmllink("", "", $page)).
- "</p>");
- }
- else {
- IkiWiki::redirect($cgi, urlto($link, undef, 1));
- }
-
- exit;
- }
-}
-
sub sessioncgi ($$) {
my $cgi=shift;
my $session=shift;
else {
$type = $config{default_pageext};
}
+
+
my @page_types;
if (exists $IkiWiki::hooks{htmlize}) {
- @page_types = grep { ! /^_/ } keys %{$IkiWiki::hooks{htmlize}};
+ foreach my $key (grep { !/^_/ } keys %{$IkiWiki::hooks{htmlize}}) {
+ push @page_types, [$key, $IkiWiki::hooks{htmlize}{$key}{longname} || $key];
+ }
}
+ @page_types=sort @page_types;
$form->field(name => 'do', type => 'hidden');
$form->field(name => 'sid', type => 'hidden', value => $session->id,
force => 1);
}
+ if (! defined $session->param('name')) {
+ # Make signinurl work and return here.
+ $form->tmpl_param(signinurl => IkiWiki::cgiurl(do => 'signin'));
+ $session->param(postsignin => $ENV{QUERY_STRING});
+ IkiWiki::cgi_savesession($session);
+ }
+
# The untaint is OK (as in editpage) because we're about to pass
# it to file_pruned anyway
my $page = $form->field('page');
my $location=unique_comment_location($page, $config{srcdir});
- my $content = "[[!_comment format=$type\n";
+ my $content = "[[!comment format=$type\n";
# FIXME: handling of double quotes probably wrong?
if (defined $session->param('name')) {
# - this means that if they do, rocks fall and everyone dies
if ($form->submitted eq PREVIEW) {
- $form->tmpl_param(page_preview =>
- previewcomment($content, $location, $page, time));
+ my $preview=previewcomment($content, $location, $page, time);
+ IkiWiki::run_hooks(format => sub {
+ $preview = shift->(page => $page,
+ content => $preview);
+ });
+ $form->tmpl_param(page_preview => $preview);
}
else {
$form->tmpl_param(page_preview => "");
IkiWiki::printheader($session);
print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
"<p>".
- gettext("Your comment will be posted after moderator review"),
+ gettext("Your comment will be posted after moderator review").
"</p>");
exit;
}
# Jump to the new comment on the page.
# The trailing question mark tries to avoid broken
# caches and get the most recent version of the page.
- IkiWiki::redirect($cgi, urlto($page, undef, 1)."?updated#$location");
+ IkiWiki::redirect($cgi, urlto($page, undef, 1).
+ "?updated#".page_to_id($location));
}
else {
if (defined $cgi->param('sid')) {
IkiWiki::checksessionexpiry($cgi, $session);
+ my $rejectalldefer=$cgi->param('rejectalldefer');
+
my %vars=$cgi->Vars;
my $added=0;
foreach my $id (keys %vars) {
if ($id =~ /(.*)\Q._comment\E$/) {
my $action=$cgi->param($id);
- next if $action eq 'Defer';
+ next if $action eq 'Defer' && ! $rejectalldefer;
# Make sure that the id is of a legal
# pending comment before untainting.
}
my @comments=map {
- my $id=$_;
+ my ($id, $ctime)=@{$_};
my $file="$config{wikistatedir}/comments_pending/$id";
my $content=readfile($file);
- my $ctime=(stat($file))[10];
+ my $preview=previewcomment($content, $id,
+ IkiWiki::dirname($_), $ctime);
{
id => $id,
- view => previewcomment($content, $id,
- IkiWiki::dirname($_), $ctime),
+ view => $preview,
}
- } comments_pending();
+ } sort { $b->[1] <=> $a->[1] } comments_pending();
my $template=template("commentmoderation.tmpl");
$template->param(
comments => \@comments,
);
IkiWiki::printheader($session);
- print IkiWiki::misctemplate(gettext("comment moderation"), $template->output);
+ my $out=$template->output;
+ IkiWiki::run_hooks(format => sub {
+ $out = shift->(page => "", content => $out);
+ });
+ print IkiWiki::misctemplate(gettext("comment moderation"), $out);
exit;
}
+sub formbuilder_setup (@) {
+ my %params=@_;
+
+ my $form=$params{form};
+ if ($form->title eq "preferences" &&
+ IkiWiki::is_admin($params{session}->param("name"))) {
+ push @{$params{buttons}}, "Comment Moderation";
+ if ($form->submitted && $form->submitted eq "Comment Moderation") {
+ commentmoderation($params{cgi}, $params{session});
+ }
+ }
+}
+
sub comments_pending () {
my $dir="$config{wikistatedir}/comments_pending/";
return unless -d $dir;
$File::Find::prune=0;
my ($f)=/$config{wiki_file_regexp}/; # untaint
if (defined $f && $f =~ /\Q._comment\E$/) {
+ my $ctime=(stat($f))[10];
$f=~s/^\Q$dir\E\/?//;
- push @ret, $f;
+ push @ret, [$f, $ctime];
}
}
}
my $preview = IkiWiki::htmlize($location, $page, '_comment',
IkiWiki::linkify($location, $page,
- IkiWiki::preprocess($location, $page,
- IkiWiki::filter($location,
- $page, $content),
- 0, 1)));
- IkiWiki::run_hooks(format => sub {
- $preview = shift->(page => $page,
- content => $preview);
- });
+ IkiWiki::preprocess($location, $page,
+ IkiWiki::filter($location, $page, $content), 0, 1)));
my $template = template("comment.tmpl");
$template->param(content => $preview);
sub commentsshown ($) {
my $page=shift;
- return ! pagespec_match($page, "*/$config{comments_pagename}*",
+ return ! pagespec_match($page, "internal(*/$config{comments_pagename}*)",
location => $page) &&
pagespec_match($page, $config{comments_pagespec},
location => $page);
if (!exists $commentstate{$page}) {
return;
}
+
+ if ($template->query(name => 'commentid')) {
+ $template->param(commentid => page_to_id($page));
+ }
if ($template->query(name => 'commentuser')) {
$template->param(commentuser =>
return $location;
}
+sub page_to_id ($) {
+ # Converts a comment page name into a unique, legal html id
+ # addtibute value, that can be used as an anchor to link to the
+ # comment.
+ my $page=shift;
+
+ eval q{use Digest::MD5 'md5_hex'};
+ error($@) if $@;
+
+ return "comment-".md5_hex($page);
+}
+
package IkiWiki::PageSpec;
sub match_postcomment ($$;@) {