Tutorial: How to optimize and style the comments.php file for WordPress

commentsJuly 29th, 2010

WordPress 3.0 is the beginning of a new era. For the first time ever, the most popular open-source blogging script has made a change to its default theme. Bye bye Kubrick, hello Twenty Ten. With that, a lot of things have changed to the default comments.php file too, which I’m going to explain to you in this tutorial, as well as show you some nifty tricks you can do to enhance the way your comments are shown. First, lets take a quick look at what I’m going to cover in this tutorial.

  1. A rundown of the new comments.php template file: what is used for what?
  2. The basics of styling your comments template.
  3. Adding different styles to every other comment.
  4. Highlighting author comments.
  5. Enable threaded comments and give them a fancy look.
  6. Add action links (edit – spam – delete) to your comments.
  7. Seperate comments and trackbacks in the functions.php file.
  8. Protect your comments against spam using PHP.
  9. Create a more useful comment pagination.
  10. Use PHP coding to disable comments on old posts.

A rundown of the new comments.php template file: what is used for what?

<div id="comments">
<?php if ( post_password_required() ) : ?>
<p class="nopassword"><?php _e( 'This post is password protected. Enter the password to view any comments.',); ?></p>
</div><!-- #comments -->
<?php
/* Stop the rest of comments.php from being processed,
* but don't kill the script entirely -- we still have
* to fully load the template.
*/
return;
endif;

This part of the coding describes what happens when a post is password protected. Visitors have to enter a certain password before they can see the comments. If they do not enter the password, or it proves to be incorrect, they won’t be able to see the comments.

<?php
// You can start editing here -- including this comment!
?>
<?php if ( have_comments() ) : ?>
<h3 id="comments-title">
<?php
printf( _n( 'One Response to %2$s', '%1$s Responses to %2$s', get_comments_number() ),
number_format_i18n( get_comments_number() ), '<em>' . get_the_title() . '</em>' );
?></h3>

This code shows what happens when there are comments. Depending on the number of comments (one or more) the title will show: “One response” or “X responses”, x being the number of comments. If we want to change the way this is displayed, we’ll have to change the div #comments-title. You can change the text that is displayed from “One Response” to “One Answer”, or to whatever you like by simply changing it in the coding mentioned above. Just make sure you don’t erase anything necessary to make the code work.

<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
<div class="navigation">
<div class="nav-previous"><?php previous_comments_link( __( '<span>&larr;</span> Older Comments') ); ?></div>
<div class="nav-next"><?php next_comments_link( __( 'Newer Comments <span>&rarr;</span>') ); ?></div>
</div> <!-- .navigation -->
<?php endif; // check for comment navigation ?>

This part takes care of the navigation, which is displayed when a post has more than a certain amount of comments. By default, WordPress doesn’t show a numbered pagination, but also previous and next links. These are displayed both at the top of the comments template and at the bottom.

<ol class="commentlist">
<?php wp_list_comments(); ?>
</ol>

Here we see the core of our comments.php file: this small piece of coding is what displays all the comments to a certain posts. Displaying comments has never been easier.

<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
<div class="navigation">
<div class="nav-previous"><?php previous_comments_link( __( '<span>&larr;</span> Older Comments') ); ?></div>
<div class="nav-next"><?php next_comments_link( __( 'Newer Comments <span>&rarr;</span>') ); ?></div>
</div><!-- .navigation -->
<?php endif; // check for comment navigation ?>

Once again, the navigation.

<?php else : // or, if we don't have comments:
/* If there are no comments and comments are closed,
* let's leave a little note, shall we?
*/
if ( ! comments_open() ) :
?>
<p class="nocomments"><?php _e( 'Comments are closed.'); ?></p>
<?php endif; // end ! comments_open() ?>
<?php endif; // end have_comments() ?>

This handles posts with no comments, and posts with comments closed. The coding is quite easy to understand.

<?php comment_form(); ?>

This is all the coding you need to display the entire comment form, with a title, name, url and email fill-in box, textarea and submit button. Nifty, eh?

</div><!-- #comments -->

Don’t forget to close the #comments div, or you might mess your coding up.

The basics of styling your comments template.

#comments {}
This is the id of the div that holds everything. With everything I mean the commentlist itself, every single comment on that specific post and the comment form.
#comments-title {}
Displays the “One Response”, “X Responses” or “No Responses” title.
ol .commentlist {}
This is an ordered list that displays all the comments. If you’re like me, and you dislike having your comments numbered, you can easily get rid of it by adding list-style-type: none; to this class.
.comment {}
The class that styles an individual comment. This is a li class.
.comment-author vcard {}
Displays the avatar in the comments.
.comment-meta commentmetadata {}
Shows the date on which the comment is posted, and other meta data.
.comment-body{}
Styles the body of the comment, basically the text of the comment itself.
#respond{}
This is the div that holds the comment form. For example, if you want to display a border around your entire comment form, including the labels for name, url, etc. you would do this here.
#reply-title{}
Title displayed above the comment form, which typically states something along the lines of “Leave a reply.”
#commentform{}
Styles the comment form itself.
#email {} #name{} #url{} #comment{}
These ids style all the labels. Naturally, email takes care of the label in which visitors have to type their email. Comment is the text area in which visitors type their comment.
#submit {}
Styles the submit button.
These are the basic styles for your comments.php file. There are a lot of other style classes and divs still, but we will discuss them later on.

Adding different styles to every other comment.

The latest versions of WordPress have made this quite easy. It’s rather useful, because it highlights your comments more and shows where one ends and the other begins. All you have to do now to accomplish this, is add two additional div classes in your stylesheet and style them.

.odd {}
A class automatically called for every odd comment.
.even {}
Class automatically called for every even comment.

If you don’t add or style these classes, your comments.php file will work just fine, and the theme will simply style your comments the way you describe in your .comment{} class.

Highlighting author comments.

Author comments can be highlighted easily nowadays. Simply add yet another class to your stylesheet.

.bypostauthor{}
By styling this differently than the other comment classes, you can add special highlights to comments written by the post author. This can be useful since users can find the author’s responses to their questions faster.
Additionally, you can choose to add a different style to comments made by logged-in users that aren’t the post author too. This is easily done by styling the following class.

.byuser{}
Both of these classes override the .comment{} .even{} and .odd{} styles when they are implemented.

Enable threaded comments and give them a fancy look.

Threaded comments are the new hype – they can enhance discussions, make it easier for the author to answer to certain questions and give your comments a forum-like vibe. But how to enable them? Well, actually WordPress makes this ridiculously easy too. All you have to do is go to your WP admin panel, choose settings, then discussion and enable threaded comments. You can choose the number of levels there too.

E.g. if you choose 3 levels Bart can leave a comment on your site, and Evelyn can reply to that. In return, John can reply to Evelyn’s comment. WordPress supports a maximum of 10 levels but I don’t advice you to actually implement that number of levels, it will make your site look very crowdy. My advice would be to keep the number of levels between 3 and 5. But that’s a personal opinion.

Now threaded comments is enabled, a “Reply” link will be added to each individual comment automatically. If a visitor clicks on this reply link, they will reply to this specific comment rather than to the post. Ofcourse this link can be styled.

.reply{}
This will style the reply link.

If you want to style your threaded comments differently, you have a lot of options. Each level can be styled differently using the following classes.

.depth-1{}
This will style all comments that are depth-1. This would be Bart’s comment.

.depth-2{}
In my example of before, this would be Evelyn’s comment. Depth-3 will then style John’s comment, and so on. You can add classes up to .depth-10{}.

ul .children{}
Styles the way the threaded comments depth-2, depth-3 and so on are listed, in an unordered list.

Because WordPress wants to fulfill all the wishes and needs of all its users, there are a couple of other additional styles you can use for threaded comments, which will enhance your comments even more.

.thread-even {}

This can be used to style all threaded even comments. In my example, Evelyn’s comment would get this style.

.thread-odd{}
Styles all odd comments, meaning Bart’s and John’s in my example.

I think we have covered practically all stylable classes and divs now. The other changes you can add to tweak your comments.php file are mostly changes in the PHP coding.

Add actions links (edit – spam – delete) to your comments.

The following tweaks I will be talking about, including this one, cannot be accomplished with the default comments.php file. We will have to change the way a single comment is displayed by default, and because of the new simplified way WordPress displays the comment lists, we will have to do this in the functions.php file. So we’ll add a bit of coding that adds changes to individual comments.

<?php
function custom_comment($comment, $args, $depth) {
$GLOBALS['comment'] = $comment; ?>
<?php // if (get_comment_type() == "comment"){ // If you wanted to separate comments from pingbacks ?>
<li <?php comment_class(); ?>>
<?php if(get_comment_type() == "comment"){ ?>
<?php echo get_avatar($comment, 80); ?>
<?php } ?>
<p><?php the_commenter_link() ?> said on
<?php if(get_comment_type() == "comment"){ ?>
<?php echo get_comment_date("j F Y") ?> at <?php echo get_comment_time(); ?>:
<span class="edit"><?php edit_comment_link('Edit', ' <span class="edit-link">(', ')</span>'); ?></span>
<span class="perma"><a href="<?php echo get_comment_link(); ?>" title="<?php _e('Direct link to this comment'); ?>">Permalink</a></span>
<?php }?>
<?php comment_text() ?>
<?php if ($comment->comment_approved == '0') echo "<p class='unapproved'>".__('Your comment is awaiting moderation.')."</p>\n"; ?>
<div class="reply">
<?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth']))) ?>
</div></li>
<?php  /*  The following is the pingback template. Will cause styling issues with odd and even styling due to threading.
}  else {
?>
<li <?php comment_class(); ?>>
<div class="comment_head cl">
<div class="user_meta" style="margin:0">
<p class="name"><strong><?php the_commenter_link() ?></strong></p>
</div>
</div>
<div class="comment_entry">
<?php comment_text() ?><?php edit_comment_link('Edit', ' <span class="edit-link">(', ')</span>');?>
</div>
<?php }*/
}
?>

Adding this to functions.php will give us a lot more control over how individual comments are displayed. By default, WordPress shows an Edit link in each comment when they are being viewed by the admin. But we can add other action links, like Spam and Delete. First, find <span><?php edit_comment_link(‘Edit’, ‘ <span>(‘, ‘)</span>’); ?></span> and add And add: <?php delete_comments_link(get_comment_ID() ); ?> right before </span>. This will add the other action links.

If we want those links to work, we will have to add an additional bit of coding to the functions.php file. Add the following to functions.php:

function delete_comment_link($id) {
if (current_user_can('edit_post')) {
echo '| <a href="'.admin_url("comment.php?action=cdc&c=$id").'">del</a>
echo '| <a href="'.admin_url("comment.php?action=cdc&dt=spam&c=$id").'">spam</a>';
}
}

Now you should see Edit – Spam – Delete action links added to your comments when you view them as post author.

Seperate comments and trackbacks in the functions.php file.

I already added the coding for this in our changed functions.php file, but disabled it for the time being. If you want to seperate trackbacks from comments, find: <?php // if (get_comment_type() == “comment”){ // If you wanted to separate comments from pingbacks ?> in functions.php.

Now delete //, like so: <?php  if (get_comment_type() == “comment”){ ?>

Protect your comments against spam using PHP.

This code looks for the HTTP referrer (the page where the request comes from) and automatically blocks the comment if the referrer is incorrect or not defined. Rather than having to install a ton of plugins, you can simply add this code to your functions.php file and your comments spam will be reduced significantly.

function check_referrer() {
if (!isset($_SERVER['HTTP_REFERER']) || $_SERVER['HTTP_REFERER'] == “”) {
wp_die( __('Please enable referrers in your browser, or, if you\'re a spammer, bugger off!') );
}
}
add_action('check_comment_flood', 'check_referrer');

Create a more useful comment pagination.

By default, you have the next bit of coding in your comments.php file:

<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
<div class="navigation">
<div class="nav-previous"><?php previous_comments_link( __( '<span>&larr;</span> Older Comments') ); ?></div>
<div class="nav-next"><?php next_comments_link( __( 'Newer Comments <span>&rarr;</span>') ); ?></div>
</div> <!-- .navigation -->
<?php endif; // check for comment navigation ?>

This is the navigation. If you have more comments than x amount (you can alter the amount in WP admin panel -> Settings), the other comments will be shown on a different page. However, rather than newer and older comment links, it might be more useful for posts with a lot of comments, to enter page numbers. You can do this easily by downloading the WP-PageNavi Plugin from Lester Chan, which adds paginating to your comments.

Once you have the plugin downloaded, uploaded to your FTP and activated, all you have to do is enter the following line of code in your PHP file:

<?php if (function_exists(‘wp_pagenavi’)) { wp_pagenavi(); } ?>

Delete everything between <div class”=navigation”> and </div> and replace it with that line of code.

However, if you’re not a fan of plugins, and you rather have some sort of hack/function you can implement to show paginated comments, Eric Martin has a nice tutorial for that.

Use PHP coding to disable comments on old posts.

You can do this easily through the admin panel by clicking Settings, and then Disable comments on posts older than x days. However, if you prefer to do this to PHP, it’s as simple as adding the following code to functions.php:
<?php
function close_comments( $posts ) {
if ( !is_single() ) { return $posts; }
if ( time() - strtotime( $posts[0]->post_date_gmt ) > ( 30 * 24 * 60 * 60 ) ) {
$posts[0]->comment_status = 'closed';
$posts[0]->ping_status    = 'closed';
}
return $posts;
}
add_filter( 'the_posts', 'close_comments' );
?>

The number 30 indicates the number of days a post may be old before it gets closed. If you change it by anything else, e.g. 14, comments will be closed after two weeks.

I hope you learned something new by reading this tutorial, and you have a more general idea of how to style and code your comments.php file to suit all your needs.

Comments are closed.

RSS Feed

Subscribe to receive the latest updates.

E-mail Subscription

Receive a mail when there is a new post.

Login to your account

Login or register to get special bonuses.