WordPress 2.7 Comment Threading

Thanks to Otto for this great post on the heads up on the new comment system for WordPress 2.7. After I read this I decided to get ahead of the curve and switch my Techozoic theme over to the new threaded commenting. I decided to take it a little further and separate pings and trackbacks from regular comments. At first this wasn’t working but after a quick email to the wp-testers list Ryan whipped up a fix for it. Anyway I figured I would explain how I did this. I continue below.


I’ll include a very simple working comment template then explain the pieces individually.

Edit Fixed a typo thanks to Otto.

<?php // Do not delete these lines
	if (!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']))
		die ('Please do not load this page directly. Thanks!');
if (function_exists('post_password_required')) 
	{
	if ( post_password_required() ) 
		{
		echo '<p class="nocomments">This post is password protected. Enter the password to view comments.</p>';
		return;
		}
	} else 
	{
	if (!empty($post->post_password)) 
		{ // if there's a password
			if ($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) 
			{  // and it doesn't match the cookie  ?>
				<p class="nocomments">This post is password protected. Enter the password to view comments.</p>
				<?php return;
			}
		}
	}
if (function_exists('wp_list_comments')) :
//WP 2.7 Comment Loop
if ( have_comments() ) : ?>
	<h3 id="comments"><?php comments_number('No Comments', 'One Comment', '% Comments' );?></h3>
	<ul class="commentlist">
		<?php wp_list_comments('type=comment'); ?>
	</ul>
	<h3>Trackbacks / Pingbacks</h3>
	<ul class="trackback">
		<?php wp_list_comments('type=pings'); ?>
	</ul>
		<div class="navigation">
			<div class="alignleft"><?php previous_comments_link() ?></div>
			<div class="alignright"><?php next_comments_link() ?></div>
		</div>
<?php else : // this is displayed if there are no comments so far ?>
	<?php if ('open' == $post->comment_status) :
		// If comments are open, but there are no comments.
	else : ?><p class="nocomments">Comments are closed.</p>
	<?php endif;
endif;
else:
//WP 2.6 and older Comment Loop
/* This variable is for alternating comment background */
		$oddcomment = 'alt';
?>

<!-- You can start editing here. -->
<?php if ($comments) : ?>
	<h3 id="comments"><?php comments_number('No comments filed', 'One comment', '% comments' );?> to &#8220;<?php the_title(); ?>&#8221;</h3> 
	<ol class="commentlist">
	<?php foreach ( $comments as $comment ) : ?>
		<li class="<?php echo $oddcomment; ?>" id="comment-<?php comment_ID() ?>">
			Comment by <em><?php comment_author_link() ?></em>:
			<?php if ($comment->comment_approved == '0') : ?>
			<em>Your comment is awaiting moderation.</em>
			<?php endif; ?>
			<br />
	<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title=""><?php comment_date('l, F jS Y') ?> at <?php comment_time() ?></a> <?php edit_comment_link('Edit','',''); ?></small>
	<?php comment_text() ?>
	</li>

	<?php /* Changes every other comment to a different class */	
		if ('alt' == $oddcomment) $oddcomment = '';
		else $oddcomment = 'alt';
	?>
	<?php endforeach; /* end for each comment */ ?>
	</ol>
 <?php else : // this is displayed if there are no comments so far ?>

  <?php if ('open' == $post->comment_status) : ?> 
		<!-- If comments are open, but there are no comments. -->
	 <?php else : // comments are closed ?>
		<!-- If comments are closed. -->
	<p class="nocomments">Comments are closed.</p>

<?php endif; ?>

<?php endif; ?>

<?php endif; // 2.6 and older Comment Loop end ?>

<?php if ('open' == $post->comment_status) : ?>
<div id="respond">
<h3>Leave a Reply</h3>
<?php if (function_exists('cancel_comment_reply_link')) { 
//2.7 comment loop code ?>
<div id="cancel-comment-reply">
	<small><?php cancel_comment_reply_link();?></small>
</div>
<?php } ?>

<?php if ( get_option('comment_registration') && !$user_ID ) : ?>
<p>You must be <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php the_permalink(); ?>">logged in</a> to post a comment.</p></div>
<?php else : ?>
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<?php if ( $user_ID ) : ?>
<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="Log out of this account">Logout &raquo;</a></p>
<?php else : ?>
<p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" />
<label for="author"><small>Name <?php if ($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" />
<label for="email"><small>Mail (will not be published) <?php if ($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
<label for="url"><small>Website</small></label></p>
<?php endif; ?>
<?php comment_id_fields(); ?>
<!--<p><small><strong>XHTML:</strong> You can use these tags: <?php echo allowed_tags(); ?></small></p>-->
<p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p>
<p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" />
<input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" />
</p>

<?php do_action('comment_form', $post->ID); ?>

</form>
</div>
<?php endif; // If registration required and not logged in ?>

<?php endif; // if you delete this the sky will fall on your head ?>

This piece here is the password protected post check. This code is backward compatible with 2.6 and older as well as the new 2.7 function.

<?php // Do not delete these lines
	if (!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']))
		die ('Please do not load this page directly. Thanks!');
if (function_exists('post_password_required')) 
	{
	if ( post_password_required() ) 
		{
		echo '<p class="nocomments">This post is password protected. Enter the password to view comments.</p>';
		return;
		}
	} else 
	{
	if (!empty($post->post_password)) 
		{ // if there's a password
			if ($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) 
			{  // and it doesn't match the cookie  ?>
				<p class="nocomments">This post is password protected. Enter the password to view comments.</p>
				<?php return;
			}
		}
	}

This is the new 2.7 comment section which functions more like the regular loop for posts now. Notice the two wp_list_comments call and the parameters given. The type parameter tells the loop which type of comment to output. Valid options are “comment, pingback, trackback, pings” pings include trackbacks and pingbacks together.

if (function_exists('wp_list_comments')) :
//WP 2.7 Comment Loop
if ( have_comments('type=comment') ) : ?>
	<h3 id="comments"><?php comments_number('No Comments', 'One Comment', '% Comments' );?></h3>
	<ul class="commentlist">
		<?php wp_list_comments('type=comment'); ?>
	</ul>
	<h3>Trackbacks / Pingbacks</h3>
	<ul class="trackback">
		<?php wp_list_comments('type=pings'); ?>
	</ul>
		<div class="navigation">
			<div class="alignleft"><?php previous_comments_link() ?></div>
			<div class="alignright"><?php next_comments_link() ?></div>
		</div>
<?php else : // this is displayed if there are no comments so far ?>
	<?php if ('open' == $post->comment_status) :
		// If comments are open, but there are no comments.
	else : ?><p class="nocomments">Comments are closed.</p>
	<?php endif;
endif;

This code is the 2.6 and older comment loop.

<?php if ($comments) : ?>
	<h3 id="comments"><?php comments_number('No comments filed', 'One comment', '% comments' );?> to &#8220;<?php the_title(); ?>&#8221;</h3> 
	<ol class="commentlist">
	<?php foreach ( $comments as $comment ) : ?>
		<li class="<?php echo $oddcomment; ?>" id="comment-<?php comment_ID() ?>">
			Comment by <em><?php comment_author_link() ?></em>:
			<?php if ($comment->comment_approved == '0') : ?>
			<em>Your comment is awaiting moderation.</em>
			<?php endif; ?>
			<br />
	<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title=""><?php comment_date('l, F jS Y') ?> at <?php comment_time() ?></a> <?php edit_comment_link('Edit','',''); ?></small>
	<?php comment_text() ?>
	</li>

	<?php /* Changes every other comment to a different class */	
		if ('alt' == $oddcomment) $oddcomment = '';
		else $oddcomment = 'alt';
	?>
	<?php endforeach; /* end for each comment */ ?>
	</ol>
 <?php else : // this is displayed if there are no comments so far ?>

  <?php if ('open' == $post->comment_status) : ?> 
		<!-- If comments are open, but there are no comments. -->
	 <?php else : // comments are closed ?>
		<!-- If comments are closed. -->
	<p class="nocomments">Comments are closed.</p>

<?php endif; ?>

<?php endif; ?>

<?php endif; // 2.6 and older Comment Loop end ?>

This code is the actual comment form. It has to be modified slightly to work with 2.7.

<?php if ('open' == $post->comment_status) : ?>
<div id="respond">
<h3>Leave a Reply</h3>
<?php if (function_exists('cancel_comment_reply_link')) {
//2.7 comment loop code ?>
<div id="cancel-comment-reply">
	<small><?php cancel_comment_reply_link();?></small>
</div>
<?php } ?>

<?php if ( get_option('comment_registration') && !$user_ID ) : ?>
<p>You must be <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php the_permalink(); ?>">logged in</a> to post a comment.</p></div>
<?php else : ?>
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<?php if ( $user_ID ) : ?>
<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="Log out of this account">Logout &raquo;</a></p>
<?php else : ?>
<p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" />
<label for="author"><small>Name <?php if ($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" />
<label for="email"><small>Mail (will not be published) <?php if ($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
<label for="url"><small>Website</small></label></p>
<?php endif; ?>
<?php comment_id_fields(); ?>
<!--<p><small><strong>XHTML:</strong> You can use these tags: <?php echo allowed_tags(); ?></small></p>-->
<p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p>
<p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" />
<input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" />
</p>

<?php do_action('comment_form', $post->ID); ?>

</form>
</div>
<?php endif; // If registration required and not logged in ?>

<?php endif; // if you delete this the sky will fall on your head ?>

Three items have to be added the the form for the comment threading to work properly.

<div id="respond">

<?php comment_id_fields(); ?>

<?php if (function_exists('cancel_comment_reply_link')) //2.7 comment loop code{ ?>
<div id="cancel-comment-reply">
	<small><?php cancel_comment_reply_link();?></small>
</div>

The first code needs to go above the comment form and wrap the entire form in the div, this way the whole form can be moved up when replying to a comment. The second code needs to go in the form somewhere, it doesn’t matter where because it is a hidden field. The last block of code needs to go underneath the Leave a reply heading, this code is the link that displays the cancel reply link.

Then last but not least this code has to be added to the header.php file above the call to wp_head.

<?php if ( is_singular() ) wp_enqueue_script( 'comment-reply' ); ?>

This is a good resource for the different styles that are used by the new comment threading.

About Jeremy Clark

Small town IT worker with interests in all things technological and technical. Biggest interests are in web development especially the WordPress publishing platform and the community supporting it. Currently developing and maintain the free WordPress theme Techozoic. I'm also always available for hire.
This entry was posted in guides, tech, wordpress and tagged , , , , . Bookmark the permalink.

28 Responses to "WordPress 2.7 Comment Threading"