X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/27193a2eeba3aa2f5ed8c0168f828149696b2b7f..f2a87addc63114edd3e096cff286bc3b19989df3:/IkiWiki/Plugin/comments.pm

diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm
index 0aa4759d8..460341710 100644
--- a/IkiWiki/Plugin/comments.pm
+++ b/IkiWiki/Plugin/comments.pm
@@ -21,6 +21,8 @@ my %commentstate;
 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);
@@ -36,6 +38,7 @@ sub getsetup () {
 		plugin => {
 			safe => 1,
 			rebuild => 1,
+			section => "web",
 		},
 		comments_pagespec => {
 			type => 'pagespec',
@@ -169,9 +172,8 @@ sub preprocess {
 		else {
 			$commentauthorurl = IkiWiki::cgiurl(
 				do => 'goto',
-				page => (length $config{userdir}
-					? "$config{userdir}/$commentuser"
-					: "$commentuser"));
+				page => IkiWiki::userpage($commentuser)
+			);
 
 			$commentauthor = $commentuser;
 		}
@@ -219,10 +221,12 @@ sub preprocess {
 	}
 
 	if (defined $params{subject}) {
-		$pagestate{$page}{meta}{title} = $params{subject};
+		# encode title the same way meta does
+		eval q{use HTML::Entities};
+		$pagestate{$page}{meta}{title} = HTML::Entities::encode_numeric(decode_entities($params{subject}));
 	}
 
-	if ($params{page} =~ m/\/(\Q$config{comments_pagename}\E\d+)$/) {
+	if ($params{page} =~ m/\/\Q$config{comments_pagename}\E\d+_/) {
 		$pagestate{$page}{meta}{permalink} = urlto(IkiWiki::dirname($params{page}), undef, 1).
 			"#".page_to_id($params{page});
 	}
@@ -375,9 +379,7 @@ sub editcomment ($$) {
 	IkiWiki::check_canedit($page, $cgi, $session);
 	$postcomment=0;
 
-	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')) {
@@ -408,8 +410,11 @@ sub editcomment ($$) {
 	my $subject = $form->field('subject');
 	if (defined $subject && length $subject) {
 		$subject =~ s/"/"/g;
-		$content .= " subject=\"$subject\"\n";
 	}
+	else {
+		$subject = "comment ".(num_comments($page, $config{srcdir}) + 1);
+	}
+	$content .= " subject=\"$subject\"\n";
 
 	$content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n";
 
@@ -419,6 +424,8 @@ sub editcomment ($$) {
 	$editcontent =~ s/"/\\"/g;
 	$content .= " content=\"\"\"\n$editcontent\n\"\"\"]]\n";
 
+	my $location=unique_comment_location($page, $content, $config{srcdir});
+
 	# This is essentially a simplified version of editpage:
 	# - the user does not control the page that's created, only the parent
 	# - it's always a create operation, never an edit
@@ -456,7 +463,7 @@ sub editcomment ($$) {
 
 		if (! $ok) {
 			my $penddir=$config{wikistatedir}."/comments_pending";
-			$location=unique_comment_location($page, $penddir);
+			$location=unique_comment_location($page, $content, $penddir);
 			writefile("$location._comment", $penddir, $content);
 			IkiWiki::printheader($session);
 			print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
@@ -552,7 +559,7 @@ sub commentmoderation ($$) {
 				if ($action eq 'Accept') {
 					my $content=eval { readfile($file) };
 					next if $@; # file vanished since form was displayed
-					my $dest=unique_comment_location($page, $config{srcdir})."._comment";
+					my $dest=unique_comment_location($page, $content, $config{srcdir})."._comment";
 					writefile($dest, $config{srcdir}, $content);
 					if ($config{rcs} and $config{comments_commit}) {
 						IkiWiki::rcs_add($dest);
@@ -731,39 +738,43 @@ sub pagetemplate (@) {
 		}
 
 		if ($shown && commentsopen($page)) {
-			my $addcommenturl = IkiWiki::cgiurl(do => 'comment',
-				page => $page);
-			$template->param(addcommenturl => $addcommenturl);
+			$template->param(addcommenturl => addcommenturl($page));
 		}
 	}
 
-	if ($template->query(name => 'commentsurl')) {
-		if ($shown) {
+	if ($shown) {
+		if ($template->query(name => 'commentsurl')) {
 			$template->param(commentsurl =>
 				urlto($page, undef, 1).'#comments');
 		}
-	}
 
-	if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
-		if ($shown) {
+		if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
 			# This will 404 until there are some comments, but I
 			# think that's probably OK...
 			$template->param(atomcommentsurl =>
 				urlto($page, undef, 1).'comments.atom');
 		}
-	}
 
-	if ($template->query(name => 'commentslink')) {
-		# XXX Would be nice to say how many comments there are in
-		# the link. But, to update the number, blog pages
-		# would have to update whenever comments of any inlines
-		# page are added, which is not currently done.
-		if ($shown) {
-			$template->param(commentslink =>
-				htmllink($page, $params{destpage}, $page,
-					linktext => gettext("Comments"),
+		if ($template->query(name => 'commentslink')) {
+			my $num=num_comments($page, $config{srcdir});
+			my $link;
+			if ($num > 0) {
+				$link = htmllink($page, $params{destpage}, $page,
+					linktext => sprintf(ngettext("%i comment", "%i comments", $num), $num),
 					anchor => "comments",
-					noimageinline => 1));
+					noimageinline => 1
+				);
+			}
+			elsif (commentsopen($page)) {
+				$link = "<a href=\"".addcommenturl($page)."\">".
+					#translators: Here "Comment" is a verb;
+					#translators: the user clicks on it to
+					#translators: post a comment.
+					gettext("Comment").
+					"</a>";
+			}
+			$template->param(commentslink => $link)
+				if defined $link;
 		}
 	}
 
@@ -811,15 +822,34 @@ sub pagetemplate (@) {
 	}
 }
 
-sub unique_comment_location ($) {
+sub addcommenturl ($) {
 	my $page=shift;
+
+	return IkiWiki::cgiurl(do => 'comment', page => $page);
+}
+
+sub num_comments ($$) {
+	my $page=shift;
+	my $dir=shift;
+
+	my @comments=glob("$dir/$page/$config{comments_pagename}*._comment");
+	return @comments;
+}
+
+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 $location;
-	my $i = 0;
+	my $i = num_comments($page, $dir);
 	do {
 		$i++;
-		$location = "$page/$config{comments_pagename}$i";
+		$location = "$page/$config{comments_pagename}${i}_${content_md5}";
 	} while (-e "$dir/$location._comment");
 
 	return $location;
@@ -827,14 +857,14 @@ sub unique_comment_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
+	# attribute 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);
+	return "comment-".md5_hex(Encode::encode_utf8(($page)));
 }
 	
 package IkiWiki::PageSpec;