Unraveling the Secrets of WordPress’ Comments.php File

Tutorial Details
  • Technology: PHP
  • Difficulty: Beginner - Intermediate
  • Difficulty: Intermediate
  • Completion Time: 1 Hour

WordPress seems to be everywhere these days, and it’s no wonder with it’s ease of use and ease of customization. In this tutorial, I’ll be dissecting the default WordPress theme’s comments.php structure and giving you various snippets of code to make your skinning easier.

For your reference, I’ve also included a small table of contents.

  1. The PHP backend
  2. General code
    1. Preventing direct access to comments.php
    2. Is a password required?
  3. Displaying the comments
    1. Basic comment template tags
    2. The final result
  4. The comment form
    1. Conditional statement overview
    2. Inserting the form
  5. Some little tricks

    1. Gravatars
    2. Comment numbers
    3. Comment links
    4. Editing comments
    5. Alternating colors for comments
    6. Displaying the allowed tags
    7. Comments RSS link
  6. Conclusion

1. The PHP Backend

<?php if(!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME'])) : ?>
<?php endif; ?>
	
<?php if(!empty($post->post_password)) : ?>
	<?php if($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) : ?>
	<?php endif; ?>
<?php endif; ?>

<?php if($comments) : ?>
	<?php foreach($comments as $comment) : ?>
		<?php if ($comment->comment_approved == '0') : ?>
		<?php endif; ?>
	<?php endforeach; ?>
<?php else : ?>
<?php endif; ?>

<?php if(comments_open()) : ?>
	<?php if(get_option('comment_registration') && !$user_ID) : ?>
	<?php else : ?>
		<?php if($user_ID) : ?>
		<?php else : ?>
		<?php endif; ?>
	<?php endif; ?>
<?php else : ?>
<?php endif; ?>

This is the raw PHP code that makes your comments.php file function. To a novice, this might look intimidating. However, do not worry: with this tutorial everything in your comments file will become crystal clear!


2. General Code

Preventing direct access to comments.php

<?php if(!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME'])) : ?>
<?php endif; ?>

This line of code prevents users from viewing comments.php by accident. This page is meant to be included in a post page, not separately. You could consider this a security measure. Inside the statement, you could insert any message you’d want to be displayed to the person viewing the comments.php file, preferably a die statement.

<?php if(!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME'])) : ?>
	<?php die('You can not access this page directly!'); ?>
<?php endif; ?>

Is a password required?

<?php if(!empty($post->post_password)) : ?>
	<?php if($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) : ?>
	<?php endif; ?>
<?php endif; ?>

This statement (well, 2 actually, but it makes more sense if you view them as one) checks whether a password is required to view the post. Obviously, if you don’t have the password to view the post, you’re also not allowed to view the comments.

The first if checks whether there is a password set. The second if statement checks whether there is a cookie with a password in place and displays the according message when it’s not there. You can customize the error message by placing whatever you choose inside the second if statement.


3. Displaying The Comments

<?php if($comments): ?>
  	<?php foreach ($comments as $comment) : ?>
		<?php if ($comment->comment_approved == '0') : ?>
		<?php endif; ?>
	<?php endforeach; ?>
<?php else : ?>
<?php endif; ?>

This first conditional statement (if($comments)) checks if there are comments and then loops through them with a foreach statement. Inside the foreach statement, you’ll notice the following conditional statement: if($comment->comment_approved == '0'). This checks if the comment has been approved, and shows a message if it’s not yet approved.

An example of this would be the following piece of code.

<?php if($comments) : ?>
	<ol>
  	<?php foreach($comments as $comment) : ?>
		<li>
			<?php if($comment->comment_approved == '0') : ?>
				<p>Your comment is awaiting approval</p>
			<?php endif; ?>
			<p>Your comment</p>
		</li>
	<?php endforeach; ?>
	</ol>
<?php else : ?>
	<p>No comments</p>
<?php endif; ?>

Basic comment template tags

To make this a functional piece of code, you’ll need to use the template tags WordPress provides.

Template TagDescription
<?php comment_ID(); ?>the ID of a comment
<?php comment_author(); ?>the author of a comment
<?php comment_author_link(); ?>the author of a comment, wrapped with a link to his website if he specified one
<?php comment_type(); ?>the type of comment; pingback, trackback or a comment
<?php comment_text(); ?>the actual comment
<?php comment_date(); ?>the date it was posted
<?php comment_time(); ?>the time it was posted

The final result

<?php if($comments) : ?>
	<ol>
  	<?php foreach($comments as $comment) : ?>
		<li id="comment-<?php comment_ID(); ?>">
			<?php if ($comment->comment_approved == '0') : ?>
				<p>Your comment is awaiting approval</p>
			<?php endif; ?>
			<?php comment_text(); ?>
			<cite><?php comment_type(); ?> by <?php comment_author_link(); ?> on <?php comment_date(); ?> at <?php comment_time(); ?></cite>
		</li>
	<?php endforeach; ?>
	</ol>
<?php else : ?>
	<p>No comments yet</p>
<?php endif; ?>

Inserting this into comments.php would give you a ordered list with the comments and the required information or display a message stating that there aren’t any comments.


4. The Comment Form

Are you still following me? Good! We’re almost there. We just need to process that comment form… Okay, maybe I lied about almost being there. The comment form is actually one of the harder parts of the entire comments.php skin file.

You’ll be bombarded with several conditional statements (is a login required, are you logged in, …). This part is where most starting skinners have the most trouble: misplacing form elements could prevent the form from working at all, without giving a specific PHP error.

To give you an insight into the conditional statements that are involved in the comment form, I’ll first be explaining those statements, and include the HTML later on explaining why it should be where it is.

Conditional statement overview

<?php if(comments_open()) : ?>
	<?php if(get_option('comment_registration') && !$user_ID) : ?>
	<?php else : ?>
		<?php if($user_ID) : ?>
		<?php else : ?>
		<?php endif; ?>
	<?php endif; ?>
<?php else : ?>
<?php endif; ?>

The first conditional statement you encounter is <?php if(comments_open()) : ?> . This basically checks if the comments are open. Obviously, if the comments are closed, you can’t post a comment and the comment form is not needed. You can put the message you want to be displayed if the comments are closed between the last <?php else : ?> and
<?php endif; ?>.

The second conditional statement (<?php if(get_option('comment_registration') && !$user_ID) : ?>) checks whether you need to be registred to post a comment and if you are logged in. If the conditional statement is fulfilled, the script should display a link to a place where users can log in. If registration is not required or you are already logged in, the script will continue with the else part and display the form.

Our final conditional statement then checks if you are logged in or not. Obviously, if you’re already logged in it’s useless to make you fill in your name, email and website again.

Inserting the form

Congratulations, we’ve plowed through all of the conditional statements in the comments.php file. Now, all that is left is to add the form in there.

The first thing I can hear you think is: where the hell is that form going to start? Well, you just have to follow common sense. The second conditional statement checks whether you have to be logged in or not, therefor you’d have to display no form until after this statement. Thus the entire form is located inside this conditional statement.

<?php if(comments_open()) : ?>
	<?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">
			<?php if($user_ID) : ?>
			<?php else : ?>
			<?php endif; ?>
		</form>
	<?php endif; ?>
<?php else : ?>
	<p>The comments are closed.</p>
<?php endif; ?>

I’ve also thrown in the link to the login page, just as I found it in the default comments.php. As I said before, the last conditional statement checks whether you’re logged in or not. Obviously, the name, email and website input fields are only displayed if you’re not logged in. Let’s throw them in there!

<?php if(comments_open()) : ?>
	<?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">
			<?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">Log out &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; ?>
		</form>
	<?php endif; ?>
<?php else : ?>
	<p>The comments are closed.</p>
<?php endif; ?>

Alright! We’re almost there! We just need to add in some simple lines of code such as a textarea and a submit button. These go after the last conditional statement, since it’s irrelevant for these elements if you are logged in or not.

<?php if(comments_open()) : ?>
	<?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">
			<?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">Log out &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; ?>
			<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>
	<?php endif; ?>
<?php else : ?>
	<p>The comments are closed.</p>
<?php endif; ?>

This code should be pretty self-explanatory. A textarea field for the comment, a submit button, a hidden input field with the comments’ future ID and a PHP snippet (<?php do_action('comment_form', $post->ID); ?>) WordPress requires to make the comment form function.

Voila! That’s all folks! You’ve now got your fully ready comments.php file. View this file to get all the PHP and HTML code that is required. You should end up with this (I simply replaced the default skin’s comments.php file with ours and added some minor styling to it.)

Comments preview

5. Some Little Tricks

Of course, you now only have a basic comments.php file. There’s tons of things you could do to further improve it. I’ll list some little tips and tricks to help you on your way.

Gravatars

As of WordPress 2.5, there is a custom WordPress template tag to embed gravatars. It pulls the gravatar from the email the visitor entered. The code to do this is very simple.

<?php echo get_avatar($author_email, $size, $default_avatar ); ?>

You can replace $author_email with the nifty get_comment_author_email(); function, $size is the height (and width) of the avatar and $default_avatar is a link to the default avatar image (displayed when the commenter has no gravatar).

Insert this code inside the foreach loop that displays the comments. The output is a image with the classes avatar and avatar-$size (where $size is the size you specified). With some minor CSS editing, you could end up with something like this:

Comment Gravatars

Comment numbers

I purposely left out headers in the comments.php file we created later, since I believed they would make for excess code in a learning process that’s difficult enough as it is. Obviously, I’m not forgetting them though.

Usually, people have a heading displaying something similar to "3 comments so far". This is really easy to achieve thanks to the template tags WordPress offers.

<?php comments_number($zero_comments, $one_comment, $more_comments); ?> 

It’s pretty self-explanatory: $zero_comments is the text to display when there are no comments, $one_comment when there is one comment and $more_comments when there are multiple comments. A real life example would be like this:

<?php comments_number('No comments', 'One comment', '% comments'); ?> 

I used % for multiple comments, since the comments_number function then replaces the % with the number of comments (2, 3, …)

Used in our comments.php file, you’ll end up with something like this:

Comment numbers

To display a link to the comments part (with the number of comments displaying aswell), you simply use the following code.

<?php comments_popup_link($zero_comments, $one_comment, $more_comments, $css_class, $comments_closed); ?> 

The first 3 parameters in this function are the same as the above comments_number function. $css_class is, obviously, the css class that you give to the <a> tag and $comments_closed is the text that should be displayed when the comments are closed. When applying this to a theme, this is a possible way to use it.

<?php comments_popup_link('No comments', 'One comment', '% comments', 'comments-link', 'Comments are closed'); ?> 

This would then give you a link with the class comments-link

Editing comments

Sometimes you’ll want to immediately edit a comment. Luckily, with the edit_comment_link function, you can easily go to the right page to edit it, instead of having to browse to your admin panel to finally reach that comment. Usage is as such:

<?php edit_comment_link($link_text, $before_link, $after_link); ?> 

You have to put this inside the foreach comment loop. Parameters are quite obvious: $link_text is the anchor text for the edit link, $before_link and $after_link respectively are the text or code to display before or after the link.

This really makes it easy to change a comment; you could simply add a small ‘Edit’ link to your comment meta information (only viewable by the admin). This is what it could look like:

Comment Edit Link

Alternating colors for comments

It’s possible that you’d want to have alternating row colors for your comments, to make a clearer separation. Doing this is relatively easy. First, add the following code to the top of the page:

function alternate_rows($i){
if($i % 2) {
echo ' class="alt"';
} else {
echo '';
} }

Then add the following inside the foreach loop (again). You could simply replace <li id="comment-<?php comment_ID(); ?>"> with this:

<?php $i++; ?>
<li<?php alternate_rows($i); ?> id="comment-<?php comment_ID(); ?>">

This will give every other comment the class alt, thus making it possible to change their appearance through CSS.

I decided to make a function for it, to have less clutter in your actual theme file. You could add the function definition into your functions.php file if you’d like to, but it makes more sense, to me, to have it at the top of your page.

Alternating rows make it easier to distinguish different comments; once implemented you might have something like this:

alternate color comments

Displaying the allowed tags

To display the code that visitors are allowed to use in their comments, simply use this little snippet.

Allowed tags: <?php echo allowed_tags(); ?>

Then you’ll simply get a list of the tags that are allowed in your comments, like this:

allowed tags

Comments RSS link

To get a link to the RSS feed for the comments of a certain post, simply insert the code below into your comments.php file on the place where you want it to be.

<?php comments_rss_link($link_text); ?>

Then simply replace $link_test with the anchor text for the RSS link.

This can come in handy if you want to give your visitors the opportunity to subscribe to the comment feed for a specific article or blog post. You could implement it like this:

comments rss link

6. Conclusion

I hope you’ve enjoyed this *ahem* little article about skinning your WordPress comments.php file. You can get the full code here, with the tricks I showed included in it:

  • gravatars,
  • alternate row colors,
  • edit link,
  • comments rss link.

Obviously, the comments link isn’t included since this has to be used inside of the loop.

Best of luck in your WordPress skinning adventures!

Tags: Wordpress
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.calvadoswebdesign.com Harry

    Hi, thanks for this amazing article, it’s been really useful, but can someone please tell me how to add another field? I need to add two more fields to this comment form and I can’t find any way to do it that works. Any help would be greatly appreciated.

  • Pingback: ‘Social Network’: Fact Or Fiction, A Tangled Web | Hernaverde13's Blog

  • Kristam

    Very Nice Tutorial…Keep it up Please..

  • Anete Hakkinen

    It is rather interesting for me to read that blog. Thanx for it. I like such topics and anything that is connected to them. I definitely want to read more soon.
    Don’t you think design should be changed from time to time?

    Anete Hakkinen
    massage monaco

  • amit

    I found this very useful
    Thanks for sharing this great tutorials.

  • http://www.shaunmbrown.com/ Shaun

    Hello,
    Curious…do you still have the html/php/css from this tutorial that you previously offered as a download? Your link has expired.
    Thanks

  • http://www.ladieskiev.com gfe kiev escort

    Cool opinion he placed here. It will be useful to read anything more concerning this article. Thanks for tell that information. Jion! With best regards!

  • http://none rafael da costa

    are there any ‘comment_content’ character limits? how can these be increased/decreased

  • Rob

    Thank you, the comments has been the hardest aspect of building your own custom wordpress theme. I dont think it could have been explained more comprehensively. Bravo.

  • Pingback: Top Collection Of WordPress Tutorials On The Web | Nerdy Geeks

  • Pingback: 135 webs/blog for wordpress tips |

  • http://www.quali-x.de wiyono

    I have error on comments.php

    Fatal error: Call to undefined function: comments_open() in /www/htdocs/wiyono/comments/comments.php on line 1

    What i have to do?

  • hafeesh

    Nice tutorial…

  • Pingback: 135 trang web/blog thủ thuật wordpress hay nhất | Ninh Bình 24h

  • http://go2websites.co.za Kingsley

    Thanks a million, great post

    My Gravatars are finally showing :)

  • Pingback: 135 trang web/blog thủ thuật wordpress hay nhất | eThongTin's Blog | Blog thủ thuật công nghệ thông tin, làm giàu cho mọi người.

  • http://www.mediairiesss.com vanga srini

    As i have viewed some valuable information here,but i feel i might recommend this kind of blog to my best close friends and family

  • Pingback: ADVANCED WORDPRESS COMMENT STYLES AND TRICKS | %home_title%

  • raj

    very nice one……….

  • Nick

    Hi thanks for the code…. I try that but when i try to add a comment to an article a get a blank wp-comments-post.php page and the comment is nor inserted in my database!!!. I switch at the default theme and i use the default comment template and it worksThen i copy the commnets template from the defaylt theme to my theme and still a blank page!!!

    I am using wordpress 3.01 any ideas?

    Thanks in advance

  • Pingback: L’Hebdo WordPress : version 3.0.5 – Tumblr – Twitter – Personnalisation | Serbouti Mohamed Amine

  • Pingback: Daveo Concept | L’Hebdo WordPress : version 3.0.5 – Tumblr – Twitter – Personnalisation

  • http://isramv.wordpress.com Israel Morales

    gracias! thank you!
    Obrigado!.

    Excelent post

  • http://www.key-logger.ws keylogger

    Hi thanks for the code…. I try that but when i try to add a comment to an article a get a blank wp-comments-post.php page and the comment is nor inserted in my database!!!.

  • http://jordantwigg.com Ryah

    posted the comments file into my own comments.php theme and i get this error when a comment is submitted?

    Warning: Cannot modify header information – headers already sent by (output started at /home/jordant1/public_html/jordantwigg.com/wp-content/themes/Jordan Twigg/functions.php:12) in /home/jordant1/public_html/jordantwigg.com/wp-includes/pluggable.php on line 897

  • http://www.aimb.ws david zw

    Alternating colors for comments you mention add some code at the top of the page What page exactly? I really want to add this to my buddy press theme so would i add this to the buddypress default theme comments.php file?
    Thanks

  • sam

    Hi,

    Thank you so much for this tutorial. :)

    I’m also wondering. Have you tried adding a registration form in wordpress?
    Can you give me some tips on how to do that.?

    thanks!

  • Test

    Testing

  • Alejandro

    Hi!
    I copied and pasted the final code to replace the original comments file, but for some reason, I get an error message and comments_open() fail.

    What can I do?

    Thanks!

  • http://supybot.org supybot.org

    This tutorial is really helping me a lot, i just try to validate my single post to w3c and validome xhtml validation. And now its VALID !

    Thanks for sharing.

  • http://www.tolvsbo.se Irian

    Hi,

    First of all: thank you for the code.

    But: from the start the code works fine, except it does not show the comments posted. It seems that the string $comments is empty, if I print_r() the string nothing shows.

    Any idea on how to solve this?
    Best regards,
    Irian

  • http://iflry.org/members/zzyngapoker.aspx Remona Ake

    Thanks a bunch for sharing this with all of us you really realize what you are talking about! Bookmarked. Please additionally consult with my website =). We will have a link exchange contract between us!

  • Nisal Periyapperuma

    How can I define a comment form in the footer?

  • Lucinda

    Thanks so much, I have been searching for my whole evening for this!! You have helped so much

  • Pingback: Unraveling the Secrets of WordPress’ Comments.php File | Tut Free

  • http://wordpressreviewtheme.co Judith

    What a thoroughly professional, complete and easy to follow Tutorial. Hearty congratulations! You have demystified the comment page. I find this an invaluable resource. Thank you!

    • kumar

      thanks

    • http://www.leveleddesign.com Marc

      +1

  • http://www.tv3arb.com sami

    very nice thanksss

  • Pingback: BlogBuzz May 21, 2011

  • http://www.rehaupvc.com rehau

    We will also be ignoring all styling elements until the very end, so if it looks bad, just be patient!

  • http://webkohder.net Sara

    Hey, this is a great article, but it needs some updating. You don’t need the extra code to set an alternating rows class in your comments, for example. Take out your classes from the list item tag and replace with the comment_class() function. That gives you odds and evens right there, plus an author class and other stuff. Also, comments_rss_link() is deprecated and replaced with post_comments_feed_link().

    I still keep coming back to this skeleton when I need to start a comments template from scratch. It’s the best I’ve found so far.

  • Pingback: Adding Form Validation to WordPress Comments using jQuery | Tut Free

  • http://gnrsu.com G.N.R.S.U

    really detail and helpful !!

  • http://ios-blog.co.uk Mark Petherbridge

    Do you have a tutorial for the comment pagination?

  • Denis

    Just what I was looking for.

    Can you also make a tutorial on how to preserve comment formatting.

    Thanks

  • http://www.idesignit.co.il/ Elron

    THANKS ALOT!
    im using it right now.

    The main problem is that i want a reply button. :\
    i look at the codex and i couldnt find a way to make replys.

    Any suggestions?

    • http://digitalrenewal.com Trisha

      ditto on that

  • http://hello hello

    dihofhofh

  • http://www.rsatechnologies.in rakesh kumar

    First Time i am able to create my own custom comments.php file, otherwise i was forced to use the default comments template file which is sometime useless or sometimes show a very unwanted results.

    Thanks you very much for this nice tutorial. Thanks a lots once more.

    • http://netzsolutions.com Amod

      Hi Jaani,

      Where are you, bhai jaan. It is really a luck to see you after long long time.
      Call me bhai jaan. Amod Sinha. 9872825962.

  • John

    Very nice!

  • http://www.treskort.com Eskort Bayan

    That was completely what i needed for wordpress thanks mate!!

  • Pingback: Noe Garcia:Blog » 22 Handy Wordpress Tuts and Hacks