Creating the WordPress Comments Section

In this final part of our Creating a WordPress Theme sub-series, we will be working on one of the most important parts of a blog: the comments section.

If you haven't been following the series, don't worry! All of these same techniques will still work on any WordPress theme.

The comments section of a blog generally has three main parts: a list of trackbacks/pingbacks, the actual comments, and the comment form. Along with those, there are also several "options", such as having comments closed, being required to be logged in to comment, and many more.

All of these will be covered in this post, to create a simple comments template.

Showing the comments template

First, in our single.php file, we will add the following code under <?php the_content(); ?>.

<div id="comments-template">
    <?php comments_template(); ?>
</div>

Now, when you look at a single post, you should also see a default comments template. But, it doesn't look like it really matches the theme, does it? We will customize our own comments template by creating a new comments.php file.

Customizing comments.php

We will be going through the entire comments template file one step at a time.

First, add the following code at the top of our comments.php file.

<?php if (!empty($post->post_password) && $_COOKIE['wp-postpass_'.COOKIEHASH]!=$post->post_password) : ?>
    <p id="comments-locked">Enter your password to view comments.</p>
<?php return; endif; ?>

This checks if a password is required to view comments, and if it is required, it will ask the user for the password.

<?php if ($comments) : ?>
 
<?php 
 
    // Set the number of Pingbacks and Comments to 0
    $numPingBacks = 0;
    $numComments  = 0;
 
    // Count the number of pingbacks to get the total amounts
    foreach ($comments as $comment) {
        if (get_comment_type() != "comment") {
            $numPingBacks++;
        } else {
            $numComments++;
        }
    }
 
    // If you would like to have striped comments:
    $thiscomment = 'odd'; 
?>

First, we create an if block checking if we have comments. If we do, we first set the number of comments and pingbacks to zero. And then, we run through a loop that actually counts the number of comments and pingbacks.

Finally, we set $thiscomment to 'odd', so that if we want, we can have different styles for odd and even numbered comments.

<?php
 
    // Loop to show trackbacks/pingbacks
    if ($numPingBacks > 0) : ?>
 
    <h2 class="comments-header"><?php _e($numPingBacks); ?> Trackbacks/Pingbacks</h2>
    <ol id="trackbacks">
 
<?php foreach ($comments as $comment) : ?>
<?php if (get_comment_type()!="comment") : ?>
 
    <li id="comment-<?php comment_ID() ?>" class="<?php _e($thiscomment); ?>">
    <?php comment_type(__('Comment'), __('Trackback'), __('Pingback')); ?>: 
    <?php comment_author_link(); ?> on <?php comment_date(); ?>
    </li>
 
    <?php
        if($thiscomment == 'odd') {
            $thiscomment = 'even';
        } else {
            $thiscomment = 'odd';
        }
    ?>
 
<?php endif; endforeach; ?>
 
    </ol>
 
<?php endif; ?>

Here, we display all of the pingbacks, if there are any. We display a header, and then we display the pingbacks in the form of an ordered list.

<?php 
 
    // Loop to show the comments
    if ($numComments != 0) : ?>
 
	<?php
	   if ($numComments == 1) {
		  echo '<h2 class="comments-header">1 Comment</h2>';
	   } else {
		  echo '<h2 class="comments-header">'.$numComments.' Comments</h2>';
	   }
	?>
 
    <ol id="comments">
 
    <?php foreach ($comments as $comment) : ?>
    <?php if (get_comment_type()=="comment") : ?>
 
        <li id="comment-<?php comment_ID(); ?>" class="<?php 
 
            _e($thiscomment); 
 
        ?>">
            <div class="comment-meta">
<span class="comment-author"><?php comment_author_link() ?></span><br />
<span class="comment-date"><?php comment_date() ?></span>
            </div>
            <div class="comment-text">
                <?php comment_text(); ?>
            </div>
        </li>
 
    <?php
        if($thiscomment == 'odd') {
            $thiscomment = 'even';
        } else {
            $thiscomment = 'odd';
        }
    ?>
 
    <?php endif; endforeach; ?>
 
    </ol>
 
    <?php endif; ?>

Here, we use a loop to display the actual comments. First of all, we check if there actually are any comments. If there are, we display a header. This displays a different header depending on the number of comments.

Then, we have an ordered list of comments. This displays all of the comment metadata, and then the actual comment text.

But, what if there are no comments? We can display a nice little message, telling the user that they can be the first to comment!

<?php
    // If no comments, show a message
    else : 
?>
 
    <h2 class="comments-header">No Comments Yet</h2>
 
    <p>You can be the first to leave a comment!</p>
 
<?php endif; ?>

The last part of our comments.php file is the comments form.

<?php if (comments_open()) : ?>
 
    <div id="comments-form">
 
	   <h2 class="comments-header">Leave a comment</h2>
 
    <?php if (get_option('comment_registration') && !$user_ID ) : ?>
        <p id="comments-blocked">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>
    <?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</a>
    </p>
 
    <?php else : ?>
 
        <p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" />
        <label for="author">Name</label></p>
 
        <p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" />
        <label for="email">E-mail</label></p>
 
        <p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" />
        <label for="url">Website</label></p>
 
    <?php endif; ?>
 
		<p><textarea name="comment" id="comment" rows="6" cols="40"></textarea></p>
 
        <p><button type="submit" name="submit" id="sub">Submit</button>
        <input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>"></p>
 
    <?php do_action('comment_form', $post->ID); ?>
 
    </form>
    </div>
 
<?php endif; ?>
 
<?php else : // Comments are closed ?>
    <p id="comments-closed">Sorry, comments for this entry are closed at this time.</p>
<?php endif; ?>

This checks if comments are open for this post. If they are, then it simply displays the comment form.

If comments are closed, it lets the user know that they cannot comment on that post.

Styling the comments

If you view a post with comments in your web browser, you should see a list of comments for that post. But, it doesn't look too nice, does it? We will go back into our style.css file and make these comments nice and pretty!

First, we will add a margin to the top of our comments section, to give it some space from the main content of the post.

#comments-template {
    margin: 2em 0 0 0;
}

We will also set the proper font size for the header of the comments section.

.comments-header {
    font-size: large;
}

Next, we will add a margin around the actual list of comments.

#comments {
    margin: 1em 2em;
}

We will also style each comment by showing the list item number, and a box around each comment.

#comments li {
    list-style-type: decimal;
    background: #1E1D1A;
 
    margin: 0 0 1em 0;
    padding: 5px 5px 2px 5px;
}

We will style the comment metadata, too, with a line to separate the metadata from the comment text, the comment author in bold, and the date in a smaller font size.

.comment-meta {
    border-bottom: 1px solid #555;
    padding: 0 0 5px 0;
}
 
.comment-meta .comment-author {
    font-weight: bold;
}
 
.comment-meta .comment-date {
    font-size: 80%;
}
 
.comment-meta a {
    color: #aaa;
}

Finally, we will style form elements, to have nice inputs and textareas.

input, textarea {
    background: #ccc;
    border: 0;
    padding: 2px;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 1em;
}

Download the finished theme

You can click here to download the finished source code for this WordPress theme. Note that some things have been left unstyled, such as blockquotes and <code> tags, but with a basic knowledge of CSS, you can easily style them yourself.

After this tutorial, there are many things that you can do to extend this theme even more, such as by enabling widgets in the sidebar, integrating certain plugins, adding an archives index page, and much, much more!

If you have any questions, or would like to tell me what you thought of this (sub-)series of tutorials, please don't hesitate to leave a comment!

Stay Updated

Did you enjoy this post? Don't miss a single post by getting free updates!