WordPress 3.0 has something very handy that I want theme authors to start implementing as soon as possible.

To show exactly why it’s so useful, I modified my own theme to start using it.


So, here’s a big hunk of code I pulled out of my current theme’s comments.php. This hunk of code has only one purpose: To display the form area where people can leave a comment:

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

<div id="respond">

<h3><?php comment_form_title( 'Leave a Reply', 'Leave a Reply to %s' ); ?></h3>

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

<?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 wp_logout_url(get_permalink()); ?>" 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><small><strong>XHTML:</strong> You can use these tags: <code><?php echo allowed_tags(); ?></code></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" />
<?php comment_id_fields(); ?>
<?php do_action('comment_form', $post->ID); ?>


<?php endif; // If registration required and not logged in ?>
<?php endif; // if you delete this the sky will fall on your head ?>

Nasty, eh? It’s a mess of if/else statements. It handles cases where the user is logged in or not, where the comments are open or closed, whether registration is required, etc. It’s confusing, difficult to modify, poor for CSS referencing…

Here’s what I replaced all that code with:

<?php comment_form(); ?>

Now then, that’s much better, isn’t it?

The comment_form function is new to 3.0. Basically, it standardizes the comments form. It makes it wonderful for us plugin authors, since now we can easily modify the comments form with various hooks and things. I’ve already modified Simple Facebook Connect and Simple Twitter Connect to support this new approach; if you’re using a theme with this, then the user won’t have to modify it to have their buttons appear on the comments form.


Since theme authors love to customize things, the comments form is also extremely customizable. Doing it, however, can be slightly confusing.

Inside the comments_form function, we find some useful hooks to let us change things around.

The first hook is comment_form_default_fields. This lets us modify the three main fields: author, email, and website. It’s a filter, so we can change things as they pass through it. The fields are stored in an array which contains the html that is output. So it looks sorta like this:

	'author' => '<p class="comment-form-author">...',
	'email'  => '<p class="comment-form-email">...',
	'url'    => '<p class="comment-form-url">...'

I truncated it for simplicity. But what this means is that code like this can modify the fields:

function my_fields($fields) {
$fields['new'] = '<p>Some new input field here</p>';
return $fields;

That sort of thing lets us add a new input field, or modify the existing ones, etc…

But fields aren’t the only thing we can change. There’s a comment_form_defaults filter too. It gets a lot of the surrounding text of the comments form. The defaults look sorta like this:

$defaults = array(
	'fields'               => apply_filters( 'comment_form_default_fields', $fields ),
	'comment_field'        => '<p class="comment-form-comment">...',
	'must_log_in'          => '<p class="must-log-in">...',
	'logged_in_as'         => '<p class="logged-in-as">...',
	'comment_notes_before' => '<p class="comment-notes">...',
	'comment_notes_after'  => '<dl class="form-allowed-tags">...',
	'id_form'              => 'commentform',
	'id_submit'            => 'submit',
	'title_reply'          => __( 'Leave a Reply' ),
	'title_reply_to'       => __( 'Leave a Reply to %s' ),
	'cancel_reply_link'    => __( 'Cancel reply' ),
	'label_submit'         => __( 'Post Comment' ),

All the various pieces of html that are displayed as part of the comment form section are defined here. So those can be modified as you see fit. However, unlike the fields, adding new bits here won’t help us at all. The fields get looped through for displaying them, these are just settings that get used at various times.

But filters are not the only way to modify these. The comment_form function actually can take an array of arguments as the first parameter, and those arguments will modify the form. So if we wanted a simple change, like to change the wording of “Leave a Reply”, then we could do this:

<?php comment_form(array('title_reply'=>'Leave a Reply, Stupid')); ?>

This gives us a simple and easy way to make changes without all the trouble of filters. Nevertheless, those filters can be very useful for more complex operations.

But wait, there’s more!

As the comments form is being created, there’s a ton of action hooks being called, at every stage. So if you want to insert something into the form itself, there’s easy ways to do it.

A quick list of the action hooks. Most of them are self-explanatory.

  • comment_form_before
  • comment_form_must_log_in_after
  • comment_form_top
  • comment_form_logged_in_after
  • comment_notes_before
  • comment_form_before_fields
  • comment_form_field_{$name} (a filter on each and every field, where {$name} is the key name of the field in the array)
  • comment_form_after_fields
  • comment_form_field_comment (a filter on the “comment_field” default setting, which contains the textarea for the comment)
  • comment_form (action hook after the textarea, for backward compatibility mainly)
  • comment_form_after
  • comment_form_comments_closed

CSS and other extras

Let’s not forget styling. All parts of the comments form have nice classes and id’s and such. Take a look at the resulting HTML source and you’ll find all the styling capabilities you like. Also, everything is properly semantic, using label tags and aria-required and so forth. All the text is run through the translation system for core translations.

So theme authors should start modifying their themes to use this instead of the existing big-ugly-comment-form code. Your users will thank you for it. Plugin authors will thank you for it. And really, it’s about time we made WordPress themes more about design and less about the nuts and bolts of the programming, no?



  1. This does not make it easier. Perhaps if WordPress had some proper documentation on each filter and a usable example it would be easier to use.

    • A filter is a filter, man. They all work pretty much the same. And adding an example for every little thing would be silly.

      • Yeah, but we don’t really know what filters *are*, because we don’t know that much about php, which we didn’t used to need in order to make WordPress *look* the way we wanted (html and css was enough). Now suddenly we need to know php to take advantages of the best practices in theming, and a lot of us are out of luck there.

        And it’s certainly not your responsibility or WordPress’ to teach us php basics. I’m just sayin’. While I picked up html, css and cgi easily enough on my own, I haven’t had much luck with php. Seems all the tutorials are either way over my head (intermediate) or so simplistic that they result in something like the Hello Dolly plugin and don’t really teach you anything you can apply elsewhere. *shrug*

        • Filters are a WordPress thing. They’re not hard.

          And since themes are written in PHP, yes, you should learn PHP in order to create themes.

          • See, I didn’t know filters were WP. I thought they were php. Not sure how I was supposed to magically know this, either.

            And yeah, I KNOW we should learn PHP. I thought I stated that clearly. What I was trying to explain is WHY we don’t know it. It’s not that we’re stupid and lazy, as so many php coders seem to think – it’s that there are no tutorials suitable for people entirely new to PHP. I’ve been trying to find them off and on for years, and they’re just not out there. (I.E., that filters article you linked to is fairly helpful, but it still assumes I know more about php than I know, and I can’t fill that gap with any php tutorials or articles I’ve come across. They’re all written for people who already know something about it.)

            • I think the reason you’re not finding such things is that no such things exist. You learn to program by reading programs and writing them. I’ve never read a basic programming tutorial in my whole life. Never seen one either.

              • …oh. Well, in that case, I’ve been doing my best for years, but I guess my mind just isn’t right for the task, because very little of php has intuitively revealed itself to me. (I can, on the other hand, reproduce pretty much any song on any instrument after hearing it once. Guess we all have different talents.)

                • Sapphire, I totally sympathise. It’s very frustrating. I recommend this good PHP Live online course at Sitepoint which, so far, has been pretty basic and made for newbies like me:

                  what’s helpful is the video: seeing things in action helps me get my head around them. It’s $29.95, so very realistic.

                  there’s nothing wrong with our brains, btw. the folks who’ve already learned this stuff don’t remember what it’s like to be a newbie, so they’re not really writing for us.

                  hope this helps.

                • Hi Sapphire,

                  I am now where you were back in September… frustrated by elliptical info and php. Totally agree with your comments. Just want to say: I bought the Head First PHP and MySql book and find that it’s a GREAT tutorial for php. I don’t think I’ll ever want to write php code though… ๐Ÿ˜‰


  2. Hi

    I would like to add a custom field to the comments section on my blog posts and your article has helped me some of the way!

    I want to capture people’s phone number but not publish it – exactly the same as with the email field.

    I’ve looked everywhere for a plugin or some code help – but I think I’ve discovered a feature that’s not been added before! In other words, there’s nothing to be found on this subject!

    I’m happy to code the comments.php file – but what I am missing is what to add to the functions.php file in order to communicate with the DB ?

    So basically, you mentioned to add this code (I assume to the functions.php file?)

    function my_fields($fields) {
    $fields['new'] = 'Phone Number (Optional. Will not be published)';
    return $fields;

    After that, what would I need to add to the comments.php file to show that field?

    And more importantly, how can I make sure this is not published !

    I would really appreciate any tips!

    • Hello. I’m having the same problem.
      I tried this in my Function.php
      function comment_header($fields) {
      $fields[‘new’] =
      ” .
      ” . __( ‘Emne’ ) . ‘ ‘ .
      ( $req ? ‘*’ : ” ) .
      ” .
      return $fields;

      And in my comment.php

      Did anyone have a answar

    • Resolved.

      I ended up redeveloping a plugin that now works a treat!

      It bascially allows you to add extra comment fields in your comments form via a plugin admin control.
      You can have them hidden or display them on your posts.

      Some manual code changes are required in comments.php template and functions.php template files, but it is straightforward and I have provided very easy and detailed instructions.

      The plugin was originally written by ideas shower (credit to them). I needed this functionality for a site I was working on and couldnโ€™t get the original code to work. I spent absolutley ages looking around the net but there seemed to be nothing that would do what I wanted!

      Anyway, I spent a fair while working on the old code in conjunction with another developer. Because of this, Iโ€™m not giving it away, Iโ€™m asking just a few bucks!

      take a look here

      I hope this helps you as much as it did me ๐Ÿ™‚

  3. Hi Otto,

    I’m trying to filter the comment form using the example you provided, in combination with the Codex article. I want to replace the html with new html. I can do that fine by creating the function my_fields($fields), specifying the new content of the author, email and url fields, and then adding the filter to comment_form_default_fields. Just like you’ve shown.

    But I would also like to retain some of the dynamic content that the default settings use. Specifically, I would like to add a class named “required” to the labels of required fields. (Instead of adding an apostrophe). I know I could do this with CSS, but really, I’m just interested in experimenting with getting dynamic content into the new comment form.

    So, in the string where I’m declaring the label’s class name, I instead tried to add the following, which the Codex says is what the default setting uses:

    blahblahblah’ . ($req ? ‘required’ : ”) . ‘blahblahblah…

    But it doesn’t output anything. If you have any suggestions for why it doesn’t work, or how to go about this, I would love to hear from you. Thanks!

  4. Thank very much for information

  5. I think the codex explains this entire functionality really well:


    Here is how I have my comments set up. A lot of these are the actual defaults. I added my own formatting as well to make it more legible.

    function sebnitu_comment_form($form_options) {

    // Fields Array
    $fields = array(

    'author' =>
    '' .
    '' . __( 'Name' ) . ' ' .
    ( $req ? '*' : '' ) .
    '' .

    'email' =>
    '' .
    '' . __( 'Email' ) . ' ' .
    ( $req ? '*' : '' ) .
    '' .

    'url' =>
    '' .
    '' . __( 'Website' ) . '' .
    '' .


    // Form Options Array
    $form_options = array(
    // Include Fields Array
    'fields' => apply_filters( 'comment_form_default_fields', $fields ),

    // Template Options
    'comment_field' =>
    '' .
    '' . _x( 'Comment', 'noun' ) . '' .
    '' .

    'must_log_in' =>
    '' .
    sprintf( __( 'You must be logged in to post a comment.' ),
    wp_login_url( apply_filters( 'the_permalink', get_permalink($post_id) ) ) ) .

    'logged_in_as' =>
    '' .
    sprintf( __( 'Logged in as %2$s. Log out?' ),
    admin_url('profile.php'), $user_identity, wp_logout_url( apply_filters('the_permalink', get_permalink($post_id)) ) ) .

    'comment_notes_before' =>
    '' .
    __( 'Your email address will not be published.' ) . ( $req ? $required_text : '' ) .

    'comment_notes_after' =>
    '' .
    sprintf( __( 'You may use these HTML tags and attributes: %s' ), '
    ' . allowed_tags() . '' ) .

    // Rest of Options
    'id_form' => 'form-comment',
    'id_submit' => 'submit',
    'title_reply' => __( 'Leave a Comment' ),
    'title_reply_to' => __( 'Leave a Reply to %s' ),
    'cancel_reply_link' => __( 'Cancel reply' ),
    'label_submit' => __( 'Post Comment' ),

    return $form_options;
    } add_filter('comment_form_defaults','sebnitu_comment_form');

  6. Ooops, it got rid of a lot of the code. Should have encoded it before posting ๐Ÿ˜›

    If you could delete the code I posted in the previous comment, here it is again encoded:

    function sebnitu_comment_form($form_options) {

    // Fields Array
    $fields = array(

    'author' =>
    '<p class="comment-form-author">' .
    '<label for="author">' . __( 'Name' ) . '</label> ' .
    ( $req ? '<span class="required">*</span>' : '' ) .
    '<input id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . ' />' .

    'email' =>
    '<p class="comment-form-email">' .
    '<label for="email">' . __( 'Email' ) . '</label> ' .
    ( $req ? '<span class="required">*</span>' : '' ) .
    '<input id="email" name="email" type="text" value="' . esc_attr( $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . ' />' .

    'url' =>
    '<p class="comment-form-url">' .
    '<label for="url">' . __( 'Website' ) . '</label>' .
    '<input id="url" name="url" type="text" value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" />' .


    // Form Options Array
    $form_options = array(
    // Include Fields Array
    'fields' => apply_filters( 'comment_form_default_fields', $fields ),

    // Template Options
    'comment_field' =>
    '<p class="comment-form-comment">' .
    '<label for="comment">' . _x( 'Comment', 'noun' ) . '</label>' .
    '<textarea id="comment" name="comment" cols="45" rows="8" aria-required="true"></textarea>' .

    'must_log_in' =>
    '<p class="must-log-in">' .
    sprintf( __( 'You must be <a href="%s">logged in</a> to post a comment.' ),
    wp_login_url( apply_filters( 'the_permalink', get_permalink($post_id) ) ) ) .

    'logged_in_as' =>
    '<p class="logged-in-as">' .
    sprintf( __( 'Logged in as <a href="%1$s">%2$s</a>. <a href="%3$s" title="Log out of this account">Log out?</a>' ),
    admin_url('profile.php'), $user_identity, wp_logout_url( apply_filters('the_permalink', get_permalink($post_id)) ) ) .

    'comment_notes_before' =>
    '<p class="comment-notes">' .
    __( 'Your email address will not be published.' ) . ( $req ? $required_text : '' ) .

    'comment_notes_after' =>
    '<p class="form-allowed-tags">' .
    sprintf( __( 'You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: %s' ), ' <code>' . allowed_tags() . '</code>' ) .

    // Rest of Options
    'id_form' => 'form-comment',
    'id_submit' => 'submit',
    'title_reply' => __( 'Leave a Comment' ),
    'title_reply_to' => __( 'Leave a Reply to %s' ),
    'cancel_reply_link' => __( 'Cancel reply' ),
    'label_submit' => __( 'Post Comment' ),

    return $form_options;
    } add_filter('comment_form_defaults','sebnitu_comment_form');

    • It is a cleaner and more formatted system to work with…

      But honestly, there s more typing and work involved. I customize just about everything in my blog theme.

      To have to write:

      ’email’ =>
      ” .
      ” . __( ‘Email’ ) . ‘ ‘ .
      ( $req ? ‘*’ : ” ) .
      ” .

      There are too many added features, which leaves more room for errors. $req, . esc_attr, and $aria_req for instance.

      Then there is the positioning of : where is this in anything that I am looking at? Everything looks like you customized it:

      function sebnitu_comment_form($form_options) {

      I see the ending ; but… should the FULL of it be placed in.

      The only reason why I reference you, is because your approach was more formatted and easier to grasp than Otto’s was.

      For people coming in that have a understanding of it to none at all and introducing this new concept… I think it is the “positioning” of where it all is that causes the confusion, and the outlining of what a filter/function is and such. BTW I hardly pay attention to Codex you basically have to read the whole of tutorials before you can begin to understand them. Adobe is a better teacher. ๐Ÿ™‚

    • Hi, I know this is an old thread, but you’re code was very useful. Unfortunately, it seems to break the logged in user link.

      It just says, ‘Logged in as . Log out?, rather than, ‘Logged in as . Log out?

      Any ideas why?
      Thanks again.

  7. Otto… more specifically dealing with your SFC plugin and comments. I have the SFC connect widget working where I can authenticate login to WordPress with Facebook. However, when you authenticate from the comments form using facebook button generated by plugin… it does not appear to log you into the site but rather just for posting a comment. How can I make it so it logs the user in just like the SFC connect and also displays the facebook profile pic for the user?

    Thanks so much for the plugin and if you can help with my dilemma!


  8. Otto,

    Thanks for the assistance! Worked wonders.

  9. My issue with this change is that it makes things far more complicated for those who are not up to speed with WordPress and those people who are just dipping their toes into PHP.

    One of the joys of WordPress in the past was how simple it was to theme, even if you had no working knowledge of WordPress or if your PHP was touch and go. When making changes to the core that require (in-depth?) knowledge of an API simply to output HTML we remove some of the simplicity that made WordPress so popular.

    • Huh? Actually it makes things far, far simpler, since you only have to add one line of code to add a comment form. That 47 line monstrosity at the beginning is way more confusing to somebody who is just learning PHP.

      And quite frankly, if your first instinct to changing the look of the page is to modify the HTML, then you’re doing it wrong. Learn CSS instead. Most things can be accomplished via CSS editing, and that should be the first place you go to change the look of the page, always.

  10. Hi,
    I added this code in the comment-template.php in order to add a new field but it only added the label and not the input field. where does the input field get added?

    function my_fields($fields) {
    $fields['new'] = 'company';
    return $fields;

    • If you want to add an input, you have to actually add the INPUT tag to that $fields[‘whatever’] variable. It doesn’t build the HTML for you.

      • Correct, my mistake.
        I added the form field this is how my code look now, and it does add the input field.
        The problem is that is show’s the company name instead of the “name” of the commenter:

        function my_fields($fields) {
        $fields['new'] = '' . __( 'company' ) . '' .
        return $fields;


        • Where in the code does wordpress output the input fields?
          I think that’s what i’M lookin for in order to add the “company” output in the comment area


          • Dan, did you ever find a solution to this? I’m actually in the same boat. I need to add a “Company” field to my comments input and would like that information to be displayed in the list of comments as well…

            • No, still haven’t found a solution.
              There is this person who has built sort of a plugin – but it still doesn’t show the fields in the comment are just in the wordpress backoffice.

              He states that the extra fields will not show up in the comment area – only after modifiying the code.


              • Hi Dan

                The comments can be shown in the actual comment form.

                I have just released an updated plugin with instructions on how to display the extra comment fields on the front end (live site).

                It just requires a bit of code manipulation in the functions.php file.

                Please email me (or see the website instructions PDF) if you would like more info! ๐Ÿ™‚

                Happy holidays

                • Hi Solace,
                  Yes I have seen your update, and have read the well documented PDF, tweaking the code at aroung line 450 in the Twentyten theme. But do you have a small demo showing how that extra field is shown in the comment area? I think that would be very very helpful.
                  A demo of code showing for instance a phone number field in the comment form and then showing the actual phone number the comment author wrote in the comment output area.
                  I think this kind of plugin could have a great potential, and alot of web / wordpress designers are looking for it.
                  Thanks again,

              • Hi Dan – I don’t have a screenshot of the extra comment field displaying on the front end comments form yet.

                However, I have tested it and the comments do display.

                Thanks for your feedback though, I will work on adding a screenshot for that over the holidays.


  11. Hello, I am building a site where user can post a letter of request to a newly elected president and his cabinet from a new democracy en West Africa.
    I modify a little the comment, but I would like to auto login news registrant. instead of having them to check their email for a password, I simply want them to use an email and choose a password right on the registration section and get login right away to post.
    any help or direction on how to accomplish that will be appreciated.

  12. Again, I would love to give the subscriber to upload their own image right from from the registration section without the need to access the back end.

  13. Hey Otto,
    Quick question. I noticed that using the comment form function adds a <!-- #respond --> comment tag. I’ve never seen any core WP function add comment tags like that one into the HTML. I’m well aware that is a minute amount of code and has ZERO effect on anything. But nonetheless, I was wondering whether that’s an accidental leftover bit of code. (Even your blog has it!)


    • Yes, using the wp_comment_list() function adds the tag at the end of the comments. It’s sort of a leftover, but the respond ID is used as part of the comment-reply javascript, to make the comment fields move to where they are needed. The actual comment field could probably be removed without issue. Hey, sometimes things get left over. ๐Ÿ™‚

  14. Thanks for the heads up. Will try to implement this in my next blog.

  15. […] wrote aย  thorough guide to comment_form in which he covers everything you ought to know about the comment_form and how to customize it, but […]

  16. I want to share with you all a solution, and to hear your opinions and feedbacks about it.

    I’ve been searching a way to add an extra field to the comment form (thanks for that, Otto), and show it on the edit-comments.php in the Admin panel, without showing it on the comment’s list itself.

    I’ve tried to use “manage_comments_columns” but this filter hook is missing, as you can see here in the WordPress hook directory.

    So i did a workaround, that i’m not very pleased with, but it works:

    // added a new field to the form
    function new_field($fields) {
    $fields['new'] = 'ื˜ืœืคื•ืŸ';
    return $fields;
    // the filter required to do so

    // add the POST of the new input field to the comment meta table and the action hook for doing so...
    add_action ('comment_post', 'add_meta_settings', 1);
    function add_meta_settings($comment_id) {
    add_comment_meta($comment_id, 'user_phone', $_POST['phone'], true);
    // the filter for adding the comment_meta to the comment text...
    add_filter( 'comment_text', 'add_phone' );

    function add_phone( $c ) {
    $referrer = get_comment_meta(get_comment_ID(),"user_phone",true);
    if ($referrer) {
    return 'phone '. $referrer .''.$c;
    } else return $c;

    And for removing it from the comments-list on the frontend site, i removed the filter before handling the list (in comments.php of my template file) with:

    remove_filter( 'comment_text', 'add_phone' );

    And set it back in the end of the file, after all handling was done:

    add_filter( 'comment_text', 'add_phone' );

    As i said, i’m not pleased with this solution, but hay… it is working… ๐Ÿ™‚

    And finally, a question (Otto, maybe you can help here?):
    I can’t seem to find how to add a cookie for the new input file on the frontend comment form. all the others inputs in the form are saved, but not my new “phone” input…

    Everyone, i would love some feedbacks,…


  17. I was mad with this form… Impossible to find the string used in the form!
    Thanks for your great tip!

  18. Hi there,

    this may be a stupid question, but: Where do I find this comments.php file? The code you showed is not in the comments.php file of my theme (twenty ten)…
    All I see is the “” tag at the end of the file. But where is the source? Where can I edit the comment-form?
    I’m using wordpress 3.0.5.

    Thanks a lot in advance! Rk

  19. @ Romak

    Twentyten by default does not include the comments form by default – it’s hidden in the functions file.


    If you want to save time and you’re interested in an easy to install, cost effective plugin, try mine! It works in Twentyten and all the hard work is done for you ๐Ÿ™‚


  20. Impossible to find the string used in the form!
    Thanks for your great tip!

  21. […] html5 3.0 and use that theme’s comment system. I have followed custom_form tutorials by Otto, Soapbox Dave, forlogos, and Deluxe Blog […]

  22. Thanks — I was just recently trying to figure out how to change the heading/title for the comment form and your post told me everything I needed to know.


  23. Hmmmm I really can’t get my head around this. I’ve looked at several blog articles, read the Codex page and posted in the forum but still can’t resolve my issue.

    I’m using this code in my comments.php file:

    '' . '' . __( 'Name' ) . ' ' . ( $req ? '*' : '' ) .
    'email' => '' . __( 'Email' ) . ' ' . ( $req ? '*' : '' ) .
    'url' => '' . __( 'Website' ) . '' .
    ); ?>

    And yet the fields do not display properly in my comment form. All I get (apart from the ‘comment’ textarea) is just some text saying ‘Array’. So obviously my code is wrong somewhere.

    Do I need to add a filter in my functions.php? I’ve tried various combinations but none have worked! If you could point me in the right direction that would be great thanks ๐Ÿ˜€

  24. If I want to change the h3 used in “reply-title” to an h2 or h1, or if I want to change the containing div into a section, how do I do that? As far as I can see I can’t do those types of changes without going into the core files, or?

    • No, you can’t, but that’s sort of the whole point. You shouldn’t want to change it from an h3 to something else. Instead, you should use CSS rules in the stylesheet to make it look the way you want it to look. If you’re wanting to change HTML to affect the display of something, then you’re doing-it-wrong ™.

      Changing the div into section is more justifiable for HTML 5 semantic support, but at the moment WP doesn’t support HTML 5 internally, and really it hasn’t gotten wide enough adoption to do so. DIV’s work just fine, and if you want to wrap the div inside a section for some reason, you can use the comment_form_before and comment_form_after action hooks to do that.

      • Just as an example, I found this page because I’m using sIFR to style all the h3 tags on my site, and this breaks the styling of the ‘cancel reply’ link on the comment form (because it’s part of the h3, and none of the things I tried in the sifr config to talk to just that part of the code worked). The five second fix to this, normally, would be to change or delete the h3 tag. It may not be the ‘best’ or ‘right’ or something I ‘should have to’ do, but it would work and work quickly. Instead, I can either spend a bunch of time troubleshooting why sIFR won’t let me style that, or a bunch of time figuring out how to talk to the comment form in such a way as to fix my problem. (I did end up finding the right hook and overwriting the cancel link with an empty space, but it was more painful than it felt like it needed to be.)

      • You see, this is exactly why I’m not going to be using the comment_form. It is not a rational assumption to expect that h3 is semantically the correct heading to use at this point on every website. In fact, in the site I’m building right now, h3 would be nonsensical here, from a semantic point of view. And, because there’s no easy way to change it, it’s actually far easier for me to go with the ‘old’ comment function. That’ll take me only a few minutes to modify into something useful.

        From my point of view, if WordPress functions spit out HTML that I can’t modify to meet a site’s need, then those functions are useless. And, yes, I can do all the CSS I like to make it look the way I want, but that won’t fix the semantics.

        • Umm, no, it is perfectly rational to expect that H3 is the semantically correct header for the comment reply form. H1 would be the main site title, H2 would be the post title, and H3 thus would be the comment reply form.

          If you are customizing the HTML to change the look of the thing, then you’re doing it wrong and perpetrating bad web design on your clients.

          • No, I’m perpetrating good design, with a slightly unusual site structure. You are making the assumption that all blogs follow exactly the same structure, and while the structure you give might be true for 95% of blogs, it isn’t an absolute. Here are a few cases where it *wouldn’t* be true:

            1) An HTML5 site. Here, comments would be a separate section with an h1 header. The comment form could, arguably, either then have an h2 header or even an h1 header, depending on the exact mark-up. WordPress can’t handle this, it appears. And it *should* be able to.

            2. A site that doesn’t use h1 for the site title. Personally, I always use an h1 for the site title, but there are plenty of designers who argue, quite legitimately, that h1 should be for the page header, or the blog title, in this case. They would then maybe use h2 for the comment form.

            3. A site that structures in the same way you suggest, but uses h3 for the whole comments section and h4 for the comments form, preferring to make the comments form a subsection of the comments section. Again, legitimate, mark-up.

            4. A site where the blog entry is actually a subsection of a page that contains other content. Here, you might want an h4, or if combined with the example above, even an h5. Admittedly, this is an edge case, but it’s not impossible.

            You can argue about how likely any of those cases are, but they are not *absolutely* impossible or even wrong, and none of them are based on using mark-up rather than CSS for appearance. They are following the semantic structure demanded by their content.

            My point is that, by choosing not to allow developers to modify certain parts of the function, WordPress is forcing these non-standard cases to not be able to use the new comments form function, and that’s a pity, because in general it *is* a much neater way of building templates.

            • … You’re seriously concerned about the semantics around the “Leave a Reply”? I’m sorry, but that’s just nitpicky as hell. Nobody should really care about that sort of thing, because *it’s not important*. Do you think Google or anybody else cares whether the title is in an H2 or an H3? Really?

              • I think it’s okay for people to feel the way you do, and to develop that way. You’re right. Most users won’t much care. Google probably won’t care. That’s true about a lot of the semantics of web development. Hell, most people won’t care if you completely ignore the hierarchy of headings completely.

                Personally, though, I do like to develop as semantically as I possibly can.

                I’m really not even suggesting that WordPress should make the comment form function customizable if the WordPress team don’t want to. But I am explaining why some developers, including me, won’t use it on all themes.

              • Accurate header structure is also used by the visually impaired to jump around within a file using header navigation capabilities within most screen readers. Having proper headers in the proper order is actually state law for public institutions in some areas (e.g., Illinois) and arguably it’s federal law as a part of the Section 508 Information Technology Accessibility Standards. In other words, it’s actually *everyone* who should care about this.

          • Yes, it might be perfectly rational to expect that, but that doesn’t mean it’s correct to force that expectation on every case which is what this is doing. It boggles my mind that so much effort has been taken to break the form out into as many pieces as it’s in, and yet something as simple as header level is hardcoded into the function. It’s perfectly reasonable to have the “reply” title an H4, and yet in order to do that you have to tear everything apart.

            If you’re forcing tags on your users in hard-to-fix portions of your framework, you’re doing it wrong and perpetrating bad semantic structure on your clients. The whole point of the HTML/CSS divide was to return semantic structure to the raw web. This is essentially the opposite case of mixing structure with design. I can’t quite tell which wrong path you’ve gone down here: are you advocating paving over broken semantics with CSS, and saying with a straight face that as long as the font size looks good then who cares? Or are you saying that every website should be built to ad-hoc wordpress assumptions, and any other method is so obviously (and I mean obvious enough to automatically hoist the blame on the developer using WP) flawed that it can only mean we’re delivering sub-par product to our clients? Both claims are outrageous.

      • The point is, it’s frustrating that WordPress has made these decisions for us. In my particular markup for the site I’m working on now, it is not semantically correct that this unimportant title would be an H3. It isn’t for WordPress to decide these things, and it’s not right that they have hijacked HTML into the backend and I gotta spend hours slogging through the comment_form array, when I could have written the form’s HTML myself in 10 minutes and been done with it.

        • If you want to roll your own in your site’s theme, then go ahead and do it. Nothing is stopping you.

          Standardizing the comment form like this isn’t for you, it’s for other people. People who want to download themes and have them work and be compatible with plugins that want to change the comment form (my STC and SFC plugins can automagically put a Facebook/Twitter connect button there, for example). Standardizing selected bits like this helps to make themes compatible with other parts of the system.

  25. Some tone in the comments here. It’s not hard to see both sides:

    I agree with Kevinjohn Gallagher – picking up WordPress theming is/was incredibly easy: just copy a good GPL (different debate) theme, give it a name, find the stuff you want to change in the templates and change them. Easy for beginners, and very simple to work with on all levels.

    On the other hand, I understand why blocks of code like the comment form should adhere to a certain standard, and why it’s important. Quite obvious, really. Of course it also makes things a lot easier for people who are happy to just drop in the form and style it a bit via CSS.

    And comment_form() is the compromise – the big problem with it is that many people will want to make sensible changes (eg text for the field labels), look at the code required to hook into the function, get scared, and replace the whole thing with the old code. In fact I’m sure there are tons of people who read this article and do the exact opposite, ie replace comment_form() with the big hunk of code at the top of this page. Why? Because it’s easier to just open comments.php and replace text.

  26. Could you tell me how to resize this comment box? In other words, it takes up way too much space and I would like to reduce the height by at least half. Pretty much the same height yours is.

    I can see the code when I inspect element from the browser, but I can’t locate it within the WordPress editor. I have no idea why and I looked in every spot I was able to find code.

    What gives?

  27. This was super-helpful and very clear. Thanks so much =)

  28. thanks was able to use this to figure out how to change some default values in my comment form. my question is the same as Bon, how do I resize the comment box? or even any input fields?

  29. Issue at hand: Default input labels Name, Email, & Website are not showing up in the Word Press Comment Box area? Why and how can it be fixed? See url: http://www.asktooltalk.com/blog/about Thanks…

  30. Otto, thank you – thank you! I didn’t do this — someone else got their fingers in there. I’m just trying to correct issues as we discover them. So how do you correct the code in the all.css file so they will display again?

  31. Otto, thanks for your help. I’ll be sending more questions your way in regards to WordPress. I donated to your beer fund… Where are you located? I’m in the United States in the WA state area. Thanks again, the toolguy…

  32. […] good job doing it. DigWP shows the comment styles for CSS. You should also visit Deluxe Blog Tips, OttoPress, and DevPress for more info on customizing the comment […]

  33. Hi Otto:

    First, thank you for your article!

    If you could answer this for me I’d really appreciate it.

    I am an HTML/CSS person who started with WP about a year ago. (I’m thinking seriously about trying to really learn php now because I’m loving this WP stuff and I hate not understanding what’s happening under the hood. But meanwhile -) I wanted a CMS environment and to be able to build dynamic sites. But I was used to designing first, then coding, and I wasn’t interested in using other people’s themes. So I bought WordPress 2.8 Theme Design (this was a few months before WP 3.0 came out) and that book used the Kubrick Theme as a reference.

    It was a pretty good guide though, and I started building my own themes. Since I primarily do “traditional websites” not blogs I didn’t need to dig into the loop much to get things working. 2 of my sites include blogs, and I used the Kubrick loop, comments.php and comments-popup.php and the blogs function. I could style them a bit – and they work. Fine.

    Now it seems I need to structure this a bit differently and so I want to understand what I’m doing.

    My first question is: do I need to add/change code from the Kubrick loop (which is pretty much the loop that is described in The Loop in Action page in the codex with some styling divs thrown in) to get things to work properly now?

    I’ve setup an unstyled barebones blog to work things through. First I had the basic loop in my index.php and the comments.php with nothing but on it and it generates the basic blog page with the “Hello World” message on it and “One Comment” which is a live link. I would click that and nothing would happen.

    I went searching through the TwentyTen loop (which has a lot in it) and found this line: so I added that to my loop, and then when I clicked on the “One Comment” link it generated a page with a Leave a Reply box – cool! But when I add the comment and click the “post comment’ nothing happens. So apparently I need to add something else.

    Here’s my current loop:

    <h2 id="post-“>
    <a href="” rel=”bookmark” title=”Permanent Link to “>

    <!– by –>

    Posted in
    <?php edit_post_link('Edit','','|‘); ?>

    Not Found

    First I just want to get the thing to be fully functional. Then I want to figure out how to style it an customize it.

    But to start, can you address the loop in relation to this whole thing?

    Or is my problem something outside the loop? Is there more I need to add to the comments.php? To the functions.php? To something else?

    Thanks, Thanks, Thanks!!

    • Otto:
      Sorry for posting twice. Second posting is the one to read. Of course I left something out.

      Where I wrote: “First I had the basic loop in my index.php and the comments.php with nothing but on it”

      I meant to say: “…and the comments.php with nothing but

      <?php comment_form(); ?>

      on it.

      And here’s my current loop:

      <?php if (have_posts()) : ?>
      <?php while (have_posts()) : the_post(); ?>
      <h2 id="post-<?php the_ID(); ?>">
      <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>">
      <?php the_title(); ?></a></h2>
      <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
      <div class="entry">
      <?php the_content('Read the rest of this entry &raquo;'); ?>
      <p class="postmetadata">
      Posted in <?php the_category(', ') ?> 
      <?php edit_post_link('Edit','','<strong>|</strong>'); ?>  
      <?php comments_popup_link('No Comments ยป', '1 Comment ยป', '% Comments ยป'); ?></p>
      <?php comments_template( '', true ); ?>
      <?php endwhile; ?>
      <div class="navigation">
      <div class="alignleft"><?php posts_nav_link('','','&laquo; Previous Entries') ?></div>
      <div class="alignright"><?php posts_nav_link('','Next Entries &raquo;','') ?></div>
      <?php else : ?>
       <h2 class="center">Not Found</h2>
       <p class="center">
      <?php _e("Sorry, but you are looking for something that isn't here."); ?></p>
      <?php endif; ?>

      Let’s see if that comes through –


      • And I left one other line out. Or rather, didn’t properly use the open and close php tags.

        The line I added to the loop was:

        <?php comments_template( '', true ); ?>

        Sorry for such a train wreck of a post!

  34. I think I figured out the problem and it’s — geez

    I thought I needed to remove ALL the code on the comments.php and replace it with the comments_form call. But I should only replace the code referencing the Respond stuff. The rest would still be necessary…sigh.

  35. I would like to add an extra field for registering (company name) in lieu of URL (website) field. Problem is I want that extra field to show up under the author name and before the IP address of the edit-comments.php page in the admin section prior to approval/deny of comment user. Please advise if your script can do such thing.

    Thank you.

  36. Thank you for this post. Most informative.

  37. The old comments.php loaded existing comments as well. How does this get addressed, I tried doing something like this but it crashes all the time…, alot of stuff is commented out, can’t get it working though..

    //add_action('comment_form_before', 'display_comments');
    function display_comments(){
    function wpthetitle(){return the_title();}
    function wpcommentsnumber(){return comments_number('No Responses', 'One Response', '% Responses' );}
    function wpcomments(){return wp_list_comments();}
    //if ( have_comments() ) : 
    echo <<<COMMENTS
    	<h3 id="comments">{$fn_comments_number()} to “{$fn_title()}”</h3>
    	<ol class="commentlist">
    	{$fn_comments()}	</ol>
  38. I think this new way to format a comment form is a bit hard to get understood at first glance.
    BTW if people wanted to just simplify the comments.php file and get rid of all that clutter for the comment form, couldn’t they just put it into a separate template file (let’s say comment-form.php) and then include it using a
    inside the comments.php?

    • <?php include (TEMPLATEPATH . '/_/inc/nav.php' ); ?>
    • Sure, but that kinda misses the point.

      The point is to create a normalized comment form, where plugins and other code can modify it and know what it will be in advance. If the theme has free reign (which it can still do), then plugins which allow things like “comment using Facebook/Twitter” and so on can’t hook into your customized form.

      A standardized form helps everybody, theme authors included. If you want to change the look of the thing, you should be using CSS, not modifying HTML or PHP code.

      • Yep, got that and thanks for clarifying this point too!
        Btw changing the markup of the form isn’t just to only change its look aesthetically: for example people might as well start to use new HTML5 form inputs (email, urlโ€ฆ), as well as HTML5 placeholder text and so on.
        Those simple modifications (just a few adds and modification to plain HTML markup) need a harder work to be implemented with this method.

        • No, not really. The comment_form function is extremely expandable and those input fields are easily modified. That’s what this entire post was about in the first place.

          • Your post is great, no doubts! Sorry if I sounded rude not saying that at first. By the way, you said too that it could be a little tricky: Since theme authors love to customize things, the comments form is also extremely customizable. Doing it, however, can be slightly confusing.

            To change a simple type attribute for a few input tags to match new HTML5 spec. I have to: make an array with the markup, then filter the wp_function with it. In my opinion that’s not so straight and to me โ€”I could be wrong about this but it looks so cause we are calling a function and a filterโ€” it looks like it’s extra work for WP.

            • Nah. Filters are fast and efficient and easy. If I wanted to change the email input to use type=email for example, this code would do it:

              function demo($fields) {
                $fields['email'] = str_replace('type="text"', 'type="email"', $fields['email']);
                return $fields;
  39. what would you do in order to put the input fields _after_ the textarea? can’t seem to finagle that.

  40. Merci beaucoup !
    Thank you for your great article !

  41. I don’t like it. Too much trouble to do something I can do faster by hand. It’s easier to just include a file with the form on it. If you want to clean up you template pages.

  42. Otto, this tutorial, while helpful, does not address the issue of rearranging comment form elements. For instance, I’d like to move the cancel_comment_reply link, but don’t know how to do this.

    I think I could do it if I had a function that provided the full code for the comment form, and a script for comments.php that would call that function.

    Then I could edit the code to move links, inputs and fields.

    Can you provide this?


  43. These kinds of tips are incredibly useful……except that I don’t see it listed anywhere WHERE this code is entered. I know my way around PHP, I just don’t know WP too well.

    I understand that we can add filters galore to functions.php, but where do these new/added $fields array variables go? Since they’re originally located in a core WP include file, and we’re not supposed to edit core files, I’m not following this.

    Presumably I call comment_form() from whatever themes page I like, but where is the comment_form() function (containing the $field array??) located? comments.php in my themes dir?

    Sorry, this has me muddled.

  44. I’m trying to change the word comment to testimonial and the text on the button to post testimonial also.
    Does anyone have any idea how and where to do this on twenty ten?

  45. […] While trying to help someone in the WP.org forums today I found a much better way to work with the WordPress comment form than I had been using in the past.  Here are two articles that I found that show how to implement it correctly. DevPress Otto […]

  46. Okay, I am brand new to all of this, so please be patient! ๐Ÿ™‚ I have a wordpress.org blog with Atahualpa theme. I installed GASP to avoid spam, but now my comments won’t work. They say to add ID); ?> into the theme’s comments editor, but I just can’t figure out WHERE to add it. Everything I’ve tried either makes no difference or it breaks it. I’ll copy and paste the coding I have, so maybe somebody can tell me where to insert. Thanks so much!!….

    comment_status)) {
    	 $bfa_page_comment_open = 1; }
    else {
    	$bfa_page_comment_open = 0;} 
    if ( have_comments() ) : ?&gt;
    	<a></a><!-- named anchor for skip links -->
    	<!-- Comment List -->
    			'reply_text'=&gt;__(' &middot; Reply','atahualpa'),
    			'login_text'=&gt;__('Log in to Reply','atahualpa'),
    			'callback' =&gt; 'bfa_comments', 
    			'type' =&gt; 'comment'
    			'reply_text'=&gt;__(' &middot; Reply','atahualpa'),
    			'login_text'=&gt;__('Log in to Reply','atahualpa'),
    			'callback' =&gt; 'bfa_comments', 
    			'type' =&gt; 'pings'
    	} else {
    			'reply_text'=&gt;__(' &middot; Reply','atahualpa'),
    			'login_text'=&gt;__('Log in to Reply','atahualpa'),
    			'callback' =&gt; 'bfa_comments', 
    			'type' =&gt; 'all'
    	} ?&gt;
    	<!-- / Comment List -->
    	comment_status) ) : ?&gt;
    		<!-- .... -->
     '' . 
    				'&nbsp;&nbsp;<strong>' . __( 'Name' ) . '</strong> ' . ( $req ? __('(required)','atahualpa') : '' ) . '',
    	'email'  =&gt; '' . 
    				'&nbsp;&nbsp;<strong>' . __( 'Email' ) . '</strong> ' . ( $req ? __('(will not be published) (required)','atahualpa') : '' ) . '',
    	'url'    =&gt; '' . 
    				'&nbsp;&nbsp;' . __( 'Website' ) . ''
    if ($bfa_ata['show_xhtml_tags'] == "Yes") {	
    	$comment_notes_after = '
    		' . 
    		sprintf(__('You can use %1$sthese HTML tags</a>','atahualpa'),
    		'<a href="#" rel="nofollow">') . '
    		<code>' . allowed_tags() . '
    } else {
    	$comment_notes_after = '';
    // The rest is set here:
    $comment_form_settings = array(
    	'fields'               =&gt; apply_filters( 'comment_form_default_fields', $fields ),
    	'comment_field'        =&gt; '',
    	'must_log_in'          =&gt; '' .  sprintf( __( 'You must be <a href="%s" rel="nofollow">logged in</a> to post a comment.' ), wp_login_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) ) ) . '',
    	'logged_in_as'         =&gt; '' . sprintf( __( 'Logged in as <a href="%1$s" rel="nofollow">%2$s</a>. <a href="%3$s" title="Log out of this account" rel="nofollow">Log out?</a>' ), admin_url( 'profile.php' ), $user_identity, wp_logout_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) ) ) . '',
    	'comment_notes_before' =&gt; '',
    	'comment_notes_after'  =&gt; $comment_notes_after,
    	'id_form'              =&gt; 'commentform',
    	'id_submit'            =&gt; 'submit',
    	'title_reply'          =&gt; __( 'Leave a Reply' ),
    	'title_reply_to'       =&gt; __( 'Leave a Reply to %s' ),
    	'cancel_reply_link'    =&gt; __( 'Cancel reply' ),
    	'label_submit'         =&gt; __( 'Post Comment' )
     $req = get_option( 'require_name_email' );

    Add this in to the function to make the required fields work.


  48. […] WordPress Ccomments-php fileHo to use twitter Avatars in CommentsUsing the WordPress Comments formWordPress 3.0 theme tip: The Comment form     Related Posts :Top 6 WordPress Theme Frameworks You Should Checkout9 […]

  49. Holla Otto and friends.

    Just thought I would let you all know that I’ve now released the WP Extra Comment Fields plugin version 2.

    It now conforms to all WP standards and is fully automated installation.
    In the planning are lots of additional features ๐Ÿ™‚


  50. I forgot to mention

    Now fully automated and compliant with WP standards ๐Ÿ™‚

    You can add extra comment fields automatically using the plugin,

    – make them public or private
    – and make them mandatory or not
    – receive them in email admin notification
    – Use radio, text fields or dropdowns!

    Lots of options ๐Ÿ™‚


Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Need to post PHP code? Wrap it in [php] and [/php] tags.