How To Change WordPress Comments From Linear to Threaded (Nested) Format

In this tutorial, I will show you how to transform comments in your WordPress blog from a Linear format into a threaded (or Nested) format without the need of a plugin. There are probably plugins that enhances commenting, but I don´t think you need any, since threaded comments feature in WordPress is not new and is available since version 2.7.

Even though, in your WordPress dashboard you can activate threaded comments and indicate the level depth, sometimes you have to make some changes to your WordPress theme for threaded comments to work. This tutorial will take you through the process with a series of steps and checks.

What is Threaded Comment Format?

Comment threading is an old WordPress feature that aids the user by visually grouping messages. As a result, there can be a hierarchy of comments displayed in a Threaded or Nested Mode. The alternative is the Linear Commenting Mode, which shows all comments in date order, regardless of who may have replied to whom. Threaded comments are displayed in a tree-like hierarchy where it is possible for users to comment on comments.

Since version 2.7, WordPress has built-in support for comment threading. However, you will not be able to make use of the Enhanced Comment feature unless your theme supports it. If your theme does not support the Threaded comment format, this tutorial will show how to add the support for threaded comments.

Why Should you Use Threaded (Nested) Comments on Your Blog

Your visitors can interact and respond to other comments easily and with less confusion, which enhances user experience.

If you receive a lot of comments, threaded comments can add a lot to the interactivity of the conversation. With Linear commenting the conversation appears broken.

With the threaded comments mode, you control the conversation by setting the level allowed in your comment thread, from 1 to 10 in your dashboard.

With default WordPress settings, comments are linear. In this case, longer discussions tend to get confusing, as the reader has to keep track of Who is responding to Whom.

You can reply to comments directly within the thread, rather than at the bottom of the Comments Section.

Emplode Theme Using Linear Commenting Format

The image below shows the Emplode theme using the Linear Commenting Format. Comments are displayed from Oldest at the top to Newest at the bottom:

Emplode theme displaying the Linear commenting format. Comments are listed from oldest to newest.

Emplode Theme Using The Threaded (Nested) Commenting Format | Final Result

The image below shows how the Comment section looks like after implementing CODE-2 AND styling it with CODE-2A below. This is what´s known as the Threaded, or Nested, Commenting format.

Emplode theme displaying the Threaded (or Nested) commenting format. Comments are listed from newest to oldest.

How To Create Threaded (Nested) Comments

Here are the 7 steps (and checklists) required to check for and create the Threaded or Nested Comments format for your WordPress blog.
Note: Threaded Comments are optional and default to OFF, that´s why it is important to start with Step 1 first.

Step 1. Login to your WordPress dashboard. In your Administration Screens, and on the Left Panel, go to Settings -> Discussion as shown in the image below. Select Enable threaded (nested) comments …, and choose the level of depth to allow. I suggest setting the depth level to 4, to keep the conversation focused.

Setting the Threaded (Nested) comments in WordPress dashboard.

Step 2. After you selected the “Enable threaded (nested) comments…” checkbox: Are your Blog comments displaying in a Threaded or Nested format? To know that, navigate to a post with comments, you will see a ´Reply´ link below each comment.

  1. If your answer is YES: Then STOP right here. Your theme already natively supports Threaded comments, and all you had to do is to enable the Nested commenting format in the dashboard. However, if you don´t like how your nested comments are styled you might want to check my CSS code (CODE-2A).
  2. If your answer is NO: Then proceed to Step 3.

Step 3. Locate your WordPress theme folder and make a Backup copy of the comments.php and style.css files. The backups are your insurance policy in case you get stuck and you need to revert back.

Step 4. Open comments.php with your preferred editor. This file is located in your theme´s folder.

Step 5. In your original comments.php file, do you see CODE-1 below or something similar?

CODE-1 :: Original comments.php file that Displays Linear Commenting format | Emplode Theme

Note: To scroll within the code: You can also click on the code window and use your keyboard´s arrow keys.

<?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 ( post_password_required() ) { ?>
	<p class="nocomments">This post is password protected. Enter the password to view comments.</p>
<?php
	return;
}
?>
<!-- You can start editing here. Emplode Theme: Creates and Displays Comments in a LINEAR format. Also creates the Comments form. -->

<?php if ( have_comments() ) : ?>

	<h3 class="left" id="comments">Comments: <?php echo $post->comment_count; ?>(From Oldest to Newest)</h3>
	<?php if ($post->comment_status == 'open') : ?>
	<p class="right"><a href="#reply">Leave a reply &#187;</a></p>
	<?php endif; ?>

	<div class="clearer">&nbsp;</div>

	<div class="left"><?php previous_comments_link() ?></div>
	<div class="right"><?php next_comments_link() ?></div>

	<div class="clearer">&nbsp;</div>

	<div class="comment_list">
	<?php foreach ( $comments as $comment ) : ?>
		<div class="comment">
			<div class="comment_gravatar left"><?php echo get_avatar( $comment, 32 ); ?></div>

			<div class="comment_author left">
				<?php comment_author_link() ?>
				<div class="comment_date"><a href="#comment-<?php comment_ID() ?>" title=""><?php comment_date('F jS, Y') ?> at <?php comment_time() ?></a> <?php edit_comment_link('Edit  comment', ' | ', ''); ?></div>
			</div>

			<div class="clearer">&nbsp;</div>
			
			<div class="comment_body">									
				<?php if ($comment->comment_approved == '0') : ?>
				<p><em>Your comment is awaiting moderation.</em></p>
				<?php endif; ?>

				<?php comment_text() ?>
			</div>				
		</div>

	<?php endforeach; ?>
	</div>

	<div class="left"><?php previous_comments_link() ?></div>
	<div class="right"><?php next_comments_link() ?></div>

	<div class="clearer">&nbsp;</div>

<?php else : ?>

	<h3 id="comments">Comments</h3>
	<p>No comments so far.</p>

<?php endif; ?>

<?php if ($post->comment_status != 'open') : ?>
	<p>(comments are closed)</p>

<?php else : ?>

<div id="reply">
	<div class="cancel-comment-reply">
		<small><?php cancel_comment_reply_link(); ?></small>
	</div>

	<?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 echo urlencode(get_permalink()); ?>">logged in</a> to post a comment.</p>

	<?php else : ?>

	<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
		<fieldset>
		<div class="legend"><h3><?php comment_form_title('Leave a Reply', 'Leave a Reply to %s' ); ?></h3></div>

	<?php if ( $user_ID ) : ?>

			<div class="form_row">
			<div style="padding: 0 12px">Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo wp_logout_url(get_permalink()); ?>" title="Log out of this account">Log out &raquo;</a></div>
			</div>

	<?php else : ?>

			<div class="form_row">											
			<div class="form_property <?php if ($req) echo "form_required"; ?>"><label for="author">Name <?php if ($req) echo "*"; ?></label></div>
			<div class="form_value"><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="28" tabindex="1" /></div>
			<div class="clearer">&nbsp;</div>
			</div>

			<div class="form_row">
											
			<div class="form_property <?php if ($req) echo "form_required"; ?>"><label for="author">Mail <?php if ($req) echo "*"; ?></label></div>
			<div class="form_value"><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="28" tabindex="2" /> (will not be published)</div>

			<div class="clearer">&nbsp;</div>
			</div>

			<div class="form_row">
											
			<div class="form_property"><label for="author">Website</label></div>
			<div class="form_value"><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="28" tabindex="3" /></div>
			<div class="clearer">&nbsp;</div>
			</div>

<?php endif; ?>

			<div class="form_row">
										
				<div class="form_property form_required">Comment</div>
				<div class="form_value"><textarea name="comment" id="comment" cols="50" rows="10" tabindex="4"></textarea></div>
				<div class="clearer">&nbsp;</div>

			</div>

			<div class="form_row form_row_submit">								
			<div class="form_value"><input type="submit" class="button" value="Submit Comment" /></div>
			<div class="clearer">&nbsp;</div>

			</div>
			<!--<p><small><strong>XHTML:</strong> You can use these tags: <code><?php echo allowed_tags(); ?></code></small></p>-->
			<div><?php comment_id_fields(); ?></div>
		</fieldset>    
        <?php do_action('comment_form', $post->ID); ?>
	</form>

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

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

Step 6. If your answer to Step 5 is NO, meaning that the code in your theme´s comments.php file is very different than CODE-1, then STOP Right Here.
However; you can continue reading to get clues on how to change the Linear commenting format into Threaded format. Remember that the function that is responsible for listing the comments is wp_list_comments().

The wp_list_comments() function displays all comments for a post or page based on a variety of parameters including ones set in the administration area (Settings -> Discussion). For instance, if you don´t tick the “Enable threaded (nested) comments…” checkbox then the wp_list_comments() function lists the comments in a linear format.

Check out the Enhanced Comment Display reference for more help.

Step 6A. If your answer to Step 5 is YES, meaning that the code in your theme´s comments.php file is similar to CODE-1, then it is generally safe to delete ALL code in your original comments.php file and replace it with the following CODE-2 below. Don´t worry, you already created a backup copy of your original comments.php file. Right?

Delete ALL code in your original comments.php file and replace it with the following CODE-2 below:

CODE-2 :: Modified comments.php file that Displays Threaded (Nested) Comments | Emplode Theme

Note: To scroll within the code: You can also click on the code window and use your keyboard´s arrow keys.

<?php
/****************************************************************************************
* @File name: comments.php
* @Description: Template Code for Creating and Displaying Threaded (Nested) Comments and 
* the Comment Form.
* @Tested on: WordPress version 3.2.1 (but it works on earlier versions up to 2.7)
*****************************************************************************************/ 
-->
<?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 ( post_password_required() ) { ?>
	<p class="nocomments">This post is password protected. Enter the password to view comments.</p>
<?php
	return;
}
?>
<!-- You can start editing here. Create and Display Threaded (Nested) comments and the Comment form. -->
<?php if ( have_comments() ) : ?>
	<h2 class="h2comments" id="comments"><?php comments_number('No Comments', '1 Comment', '% Comments' );?></h2>

	<ul class="commentlist" >
	<?php wp_list_comments(); ?>
	</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. -->
	 <?php else : // comments are closed ?>
		<!-- If comments are closed. -->
		<p class="nocomments">Comments are closed.</p>
	<?php endif; ?>
<?php endif; ?>

<?php if ('open' == $post->comment_status) : ?>

<div id="respond">

<h2 id="commentsForm" class="clear"><?php comment_form_title( 'Anything to say? Leave a comment!', 'Leave a comment to %s' ); ?></h2>

<div class="cancel-comment-reply">
<?php cancel_comment_reply_link(); ?>
</div>

<?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 echo urlencode(get_permalink()); ?>">logged in</a> to post a comment.</p>
<?php else : ?>

<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<fieldset>
<?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 wp_logout_url(get_permalink()); ?>" title="Log out of this account">Log out &raquo;</a></p>

<?php else : ?>

<p class="form_row"><label for="author">Name: <?php if ($req) echo "(required)"; ?></label>
<input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" <?php if ($req) echo "aria-required='true'"; ?> />
</p>

<p class="form_row"><label for="email">Mail: (will not be published) <?php if ($req) echo "(required)"; ?></label>
<input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" <?php if ($req) echo "aria-required='true'"; ?> />
</p>

<p class="form_row"><label for="url">Website:</label>
<input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
</p>

<?php endif; ?>

<p class="form_row"><label for="comment">Comment:</label>
<textarea name="comment" id="comment" cols="45" rows="10" tabindex="4"></textarea></p>
<!--<p><small><strong>XHTML:</strong> You can use these tags: <code><?php echo allowed_tags(); ?></code></small></p>-->
<p><input name="submit" type="submit" id="submit" tabindex="5" value="POST COMMENT" />
<?php comment_id_fields(); ?>
</p>

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

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

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

CODE-2 Notes:

The most important function is wp_list_comments() on Line 25 of the code.

CODE-2 works on WordPress 2.7 and above. But I hope that you will upgrade to the latest WordPress version.

CODE-2 is XHTML and HTML5 valid.

Modify CODE-2 to fit your blog!

There is another way (and probably better and more efficient way), to write CODE-2. I will discuss it in a separate tutorial.

Styling the Comment Section | style.css

Finally we need to style the Comments Section (this is Step 7, if you like). We need to style both the list of comments AND the comment form, with CSS. CODE-2A is what I used for the “Emplode Theme” of this blog. The code should be added to your theme´s CSS file (called style.css).

CODE-2A :: Comments Section | Emplode theme

Note: To scroll within the code: You can also click on the code window and use your keyboard´s arrow keys.

/******************************************************************************
* @Author: Boutros AbiChedid 
* @Date:   December 10, 2011
* @Websites: http://bacsoftwareconsulting.com/ ; http://blueoliveonline.com/
* @Description: CSS code for the Comments Section including the Comment form. 
* The styling works for both Linear and Threaded (Nested) Comment format. 
* @Tested on: IE7/IE8/IE9, Safari 5 (for windows), Google Chrome 15, Opera 11.5 
* and Mozilla Firefox 8
*******************************************************************************/ 
/* ---------- Styling Comment List (Linear and Threaded) ----------*/
h2.h2comments {
display:block;
clear:both;
border-bottom:1px #bbb solid;
padding:10px 0 5px 5px;
margin:20px 0 0 0;
}
h2.h2comments a.addComment {
display:block;
text-transform:uppercase;
float:right;
font-size:12px;
margin-top:-3px;
padding-top:8px;
margin-right:10px;
font-weight:bold;
}
h2.h2comments a.addComment:hover {
text-decoration:none;
}
h2#commentsForm {
margin:15px 0;
padding-top:15px;
}
ul.commentlist {
list-style:none;
list-style-position:outside;
display:block;
padding-bottom:30px;
overflow:hidden;
border-bottom:1px #bbb solid;
}
ul.commentlist ul {
list-style-type:none;
list-style:none;
list-style-position:outside;
margin:0;
}
ul.commentlist li {
position:relative;
margin:25px 0 0;
list-style:none;
}
.commentlist li{
list-style:none !important; /*Important to override any previous styling */
}
ul.commentlist li p{
margin:5px 0;
padding:5px 0;
}
ul.commentlist li .comment-meta, ul.commentlist li .text  {	
font-style:italic;
font-size:11px;
text-align:justify;
}
ul.commentlist li .comment-meta span {
font-size:11px;
color:#999;
}
.comment-meta p {
text-align:justify;
}
ul.commentlist li .avatar {
background:#F8F7F1;
border:1px solid #FFF;
padding:3px;
float: left;
margin: 1px 8px 8px 0;
}
ul.commentlist .reply {
font-size:10px;
width:100%;
border-bottom:1px #ccc dotted;
padding-bottom:1px;
}
ul.commentlist .reply a {
background:#F7F3C5;
padding:3px;
border:1px dotted #bbb;
border-bottom:none;
list-style:none;
}
ul.commentlist .reply a:hover {
text-decoration:none;
}
ul.commentlist li .children {
margin-left:45px;
border-left:1px dotted #bbb;
padding-left:5px;
}

/* ----------- Styling the Comment FORM -----------*/
#commentform p {
margin:0;
padding:0;
}
#commentform label {
display:block;
padding:5px 0;
}
#commentform input, #commentform textarea {
padding:7px;
font-style:italic;
border:none;
font-family:Georgia, "Times New Roman", Times, serif;
font-size:12px;
color:#999;
margin:0 0 7px;
}
#commentform input {
width:300px;
}
#commentform textarea{
font-size:13px;
overflow: auto;
width:400px;
}
#commentform input#submit{
width:161px;
height:32px;
margin-top:10px;
cursor:pointer;
font-style:normal;
background:#333;
font-size:12px;
color:#bbb;
}
#commentform input#submit:hover{
background:#666;
color:#eee;
}
#commentform small {
font-size:11px;
line-height:10px;
}
.alignleft {
float:left;
margin:5px 15px 5px 0;
}
.alignright {
float:right;
margin:5px 0 5px 15px;
}
fieldset {
border:0;
margin:0.2em 0.1em;
padding:0.4em;
}
.form_row {
font-weight:bold;
font-size:104%;
}
.cancel-comment-reply{
font-variant:small-caps;
font-size:90%;
padding-top:0;
margin-top:0;
}

CODE-2A Notes:

If you decide to use my CSS code above in its entirety, make sure to DELETE the styling that relates to the Comments section (and the Comment form) in your style.css file. In other words, you theme´s CSS file has already styling for the comments section, you need to delete this first. Don´t worry, you already created a backup copy of your original style.css file. Right?

If you have good knowledge with CSS, feel free to modify CODE-2A to fit the design of your blog. I tried to keep the styling neutral so that you have less tweaking to do.

CODE-2A is CSS valid.

CODE-2A is tested to display properly with all major browsers. IE7/IE8/IE9, Safari 5 (for windows), Google Chrome 15, Opera 11.5
and Mozilla Firefox 8. The code was NOT tested for IE6 (and I don´t care if it does not work).

Both CODE-2 AND CODE-2A work together (as a team). If you modify anything in CODE-2, make sure that styling is also updated if needed.

Your Turn to Talk

In this tutorial, I showed you how to activate and create Threaded (Nested) Comments formatting for your WordPress Blog without the need of a plugin that you can style to best fit your needs.

I also showed you how to update your theme´s files to add the support for Threaded comments. So if you don´t have threaded comment format in your blog, it is time to do so. It will transform your comments section to a more lively and less confusing discussion, especially if you get a lot of comments.

How easy did you find this tutorial to implement? Do you have a hard time integrating the code into your WordPress theme? Do you have something to add or anything else to say? If so, please share your opinion or questions in the comments section. Your opinion matters, unless it is a Spam.

If you enjoyed this post, please consider: linking back to it, subscribing by email to future posts, or subscribing to the RSS feed to have new articles delivered to your feed reader, or feel free to donate. Thanks!

About the Author |
Boutros is a professional Drupal & WordPress developer, Web developer, Web designer, Software Engineer and Blogger. He strives for pixel perfect design, clean robust code, and user-friendly interface. If you have a project in mind and like his work, feel free to contact him. Connect with Boutros on Twitter, and LinkedIn.
Visit Boutros AbiChedid Website.

3 Responses to “How To Change WordPress Comments From Linear to Threaded (Nested) Format”

  1. Thank you so much for this!!! It worked like a charm on an old WordPress theme called Deliciously Blue. I appreciate your effort to write such great instructions.

  2. jay says:

    Hi if i try to validate this using theme-check it displays the following

    REQUIRED: Could not find comment_form. See: comment_form which i understand is wordpress default comment functionality.