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.

Demonstration

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>
</div>

<?php if ( get_option('comment_registration') && !$user_ID ) : ?>
<p>You must be <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php echo urlencode(get_permalink()); ?>">logged in</a> to post a comment.</p>
<?php else : ?>

<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">

<?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(); ?>
</p>
<?php do_action('comment_form', $post->ID); ?>

</form>

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

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.

Customizing

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:

array(
	'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;
}
add_filter('comment_form_default_fields','my_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?

Related posts:

  1. Comment Form Autocomplete Snippet
  2. WordPress 3.0 Theme Tip: Feed Links
  3. WordPress Theme Tip: Force an Image Size
  4. WordPress 3.0 Theme Tip: Custom Backgrounds
  5. Minimum WordPress Theme Requirements
Shortlink:

205 Comments

  1. says:

    Ok so I want to use the hook comment_form_before and have it execute some php how do I do that?

  2. says:

    Hi! This is okey and I’ve red and understood it from codex, BUT there is some qstn please, how to customize html around submit button? I can change text – okey, but I can’t see where I could paste a piece of code so that my button was stylish. Guys please help me, because my defaulte theme has a tone of codes, I did it all except of that button, really really appriciate for your help

    • Alex says:

      Are you talking about changing the look of the button entirely? if you want to to do that then its best you style it through css.
      For example the submit button will have an ‘id’ which will most likely be: id=”submit”; you should then find that id in the css and use the background-image: url() to link to the image you would want your reply button to look like.
      I think that should do it, if there is still trouble, shout :)

  3. [...] you would like to learn more about customization of the comment form, you might want to check out WordPress 3.0 Theme Tip the Comment Form. Step 10 – Page.php When you create a page in WordPress, a different file is used to display the [...]

  4. lauren says:

    This is very useful, but I am lost as to what you are meant to do with:

    array(
    2 ‘author’ => ‘…’,
    3 ‘email’ => ‘…’,
    4 ‘url’ => ‘…’
    5 );

    Does this array get passed as args? Does this get added into a filter somewhere? I appreciate your post, but it can be very difficult for novices when code snippets get taken out of context….

    Thanks

  5. says:

    I have removed the “Website” field on my site but still some people commenting with their website .. can anybody tell me how?

  6. says:

    Hi,
    Good help provided by you, but i want to change on my site http://makeadvice.com/ comment looks only, not a field, for me field is ok, just want to change a look, kindly provide some info, for the same, thanks .

  7. Barry says:

    Hi thanks for this,
    You explain how to add an extra field, but how do you remove one. I don’t want to display the website field.

    Thanks :)

  8. [...] Otto Share this:Like this:LikeBe the first to like this post. This entry was posted in Code and tagged Comments, WordPress by Nick Hamze. Bookmark the permalink. [...]

  9. Alex says:

    Also, where does the comment approval function occur (where admins approve or disapprove comments). I’d like to provide additional fields on a comment so that the admin can make adjustments to comments in the admin area, not the actual comment form.

  10. says:

    Hi, awesome post.

    I’m not a coder, so I was wondering how can I add Google Analytics event tracker to the submit button? I use a twenetyeleven child theme.

    I need to add onClick:
    Example: <input name="submit" type="submit" id="submit" onClick="_gaq.push(['_trackEvent', 'Forms', 'Submit', 'BlogComments']);" tabindex="5" value="” />

    Anyone got any ideas?

  11. Thank you very much for sharing this great article. I’m trying to make a wp theme curently. It’s good reference. Thank you.

  12. says:

    I would like to remove the log in/ logout text buttons any way to do this?

  13. says:

    I have removed the “Website” field on my site but still some people commenting with their website .. can anybody tell me how?

  14. says:

    I’m having a really hard time with only one thing…

    I have the one line of code in comments.php, and in single.php I have , but where are the comments actually displayed? I cannot figure this out. I’ve looked in the codex and in tons of forums, but no one else even seems to be having this problem!

  15. yura says:

    Thanks a lot it helped me a lot.

  16. says:

    I solved this making a “not smart solution” based on commeting the function comment_form and writing directly the expected html generated code with the onclick information. The only thing that you need is to use the getID(), the_permalink(); and $_SERVER['REQUEST_URI'] to complete the dynamic parameters.

    Albert.

Leave a Reply

Your email address will not be published. Required fields are marked *

Connect with Facebook

*

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=""> <strike> <strong>

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