Adding Custom Fields In WordPress’ Comment Form
If you have created websites or blogs, then you need no introduction to WordPress, one of the most popular content management systems (CMS). WordPress powers millions of websites, for individuals as well as big companies. Why is it so successful?
Apart from its ease of use and the availability of themes and plugins, WordPress can be easily modified to include custom features and functions. Hooks and filters are built into the CMS that allow you to add functionality or strip out something that is not required. You can customize the way WordPress handles content as well as comments. For example, you could require readers to leave their phone number and/or address when leaving a comment.
You might want them to say whether they liked your blog post. You could have any one of thousands of reasons for adding input fields to the comment form on your WordPress website. So, how do you extend the WordPress comment form with a custom input field?

Flickr/Neal
In this article, we will add three input fields to the comment form of a WordPress website: two text-input fields (for a phone number and comment title) and a radio option for rating the current article. We will use the add_comment_meta function to add a meta data field to comments. In the process, we will also modify the comment form using the comment_form_default_fields filter and the comment_form_after_fields and comment_form_logged_in_after actions. And we will use many more functions to achieve the desired result.
We can extend the comment form by editing the theme or by creating a theme that alters the behavior of the active theme to include the additional input fields. Modifying the theme is relatively easier to do, but it has an obvious limitation: all the effort that has gone into customization will be for nought if the theme is replaced. Using a plugin to customize the comment form frees us from this limitation. This way, the customized comment form will apply to all themes (except those that have non-standard methods for adding the comment form). Let’s take the plugin route, to avoid having to go through the entire coding process in case we switch themes. We will call our plugin “Extend Comment.”
Open your text editor of choice (Notepad, Notepad++, BlueFish, etc.), and create a new file, extendcomment.php. Make sure to save it in a folder of the same name, ExtendComment, to keep the organization of files simple. As the first step in our coding, let’s add the headers for our WordPress plugin. The headers are pretty much self-explanatory:
<?php
/*
Plugin Name: Extend Comment
Version: 1.0
Plugin URI: http://smartwebworker.com
Description: A plugin to add fields to the comment form.
Author: Specky Geek
Author URI: http://www.speckygeek.com
*/
Now, we need to start actually adding the input fields. We’ll start by adding a text input field for a phone number. We will add it to the default fields of the comment form for collecting the author’s information. The default fields are for name, email address and website URL. This set of input fields is hidden if the user is logged in. In the code below, we have recalled the information of the logged-in user as well as the information on whether a field is required. We have modified all of the default fields and added a field for a phone number by creating an array with our settings and passing it through a filter.
// Add custom meta (ratings) fields to the default comment form
// Default comment form includes name, email address and website URL
// Default comment form elements are hidden when user is logged in
add_filter('comment_form_default_fields', 'custom_fields');
function custom_fields($fields) {
$commenter = wp_get_current_commenter();
$req = get_option( 'require_name_email' );
$aria_req = ( $req ? " aria-required='true'" : '' );
$fields[ '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" tabindex="1"' . $aria_req . ' /></p>';
$fields[ '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" tabindex="2"' . $aria_req . ' /></p>';
$fields[ '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" tabindex="3" /></p>';
$fields[ 'phone' ] = '<p class="comment-form-phone">'.
'<label for="phone">' . __( 'Phone' ) . '</label>'.
'<input id="phone" name="phone" type="text" size="30" tabindex="4" /></p>';
return $fields;
}
In the next step, we have to add a text field for the comment’s title and a radio list for rating the article. These fields cannot be added to the default fields for the author’s information above because even logged-in users will need to input these. This time we have not filtered any default function, but we have added new actions altogether. The comment_form_logged_in_after action adds the input fields below the status message that is displayed to logged-in users, just above the comment input box. It will not be activated for users who are not logged in. To show the input fields to non-logged-in users, we have added the comment_form_after_fields action, which displays the fields below the default fields for the author’s information. We have marked the rating field as required, which we’ll take care of later. Instead of using plain HTML for the radio input boxes, we have used simple code that runs a loop and renders the input boxes with the relevant values until there are five of them.
// Add fields after default fields above the comment box, always visible
add_action( 'comment_form_logged_in_after', 'additional_fields' );
add_action( 'comment_form_after_fields', 'additional_fields' );
function additional_fields () {
echo '<p class="comment-form-title">'.
'<label for="title">' . __( 'Comment Title' ) . '</label>'.
'<input id="title" name="title" type="text" size="30" tabindex="5" /></p>';
echo '<p class="comment-form-rating">'.
'<label for="rating">'. __('Rating') . '<span class="required">*</span></label>
<span class="commentratingbox">';
//Current rating scale is 1 to 5. If you want the scale to be 1 to 10, then set the value of $i to 10.
for( $i=1; $i <= 5; $i++ )
echo '<span class="commentrating"><input type="radio" name="rating" id="rating" value="'. $i .'"/>'. $i .'</span>';
echo'</span></p>';
}
Our comment form has the input fields, but they are useless until we have a system for saving the data inputted by users. By adding an action to the comment_post hook, we devise a method for saving the values of meta data if these are not blank. We should make sure not to save blank meta data fields in order to keep the database table from being cluttered with empty rows. We’re also sanitizing the inputted data using the wp_filter_nohtml_kses filter.
Here is the default usage of the add_comment_meta function:
add_comment_meta($comment_id, $meta_key, $meta_value, $unique = false)
In the code, $comment_id is the comment’s default ID set by WordPress. It will be left as is to allow for processing of all comments. The $meta_key stands for the names of the fields as set by us. In this case, the meta keys are the phone number, comment title and rating. Here is how we implement the function in our plugin:
// Save the comment meta data along with comment
add_action( 'comment_post', 'save_comment_meta_data' );
function save_comment_meta_data( $comment_id ) {
if ( ( isset( $_POST['phone'] ) ) && ( $_POST['phone'] != '') )
$phone = wp_filter_nohtml_kses($_POST['phone']);
add_comment_meta( $comment_id, 'phone', $phone );
if ( ( isset( $_POST['title'] ) ) && ( $_POST['title'] != '') )
$title = wp_filter_nohtml_kses($_POST['title']);
add_comment_meta( $comment_id, 'title', $title );
if ( ( isset( $_POST['rating'] ) ) && ( $_POST['rating'] != '') )
$rating = wp_filter_nohtml_kses($_POST['rating']);
add_comment_meta( $comment_id, 'rating', $rating );
}
Remember marking the ratings field as required? Let’s tell WordPress to refuse comments without a rating. We’ll add a function to the preprocess_comment filter that will be applied to the comment data before it is saved. We’re checking whether the ratings field is empty and then displaying an error message if it is.
// Add the filter to check whether the comment meta data has been filled
add_filter( 'preprocess_comment', 'verify_comment_meta_data' );
function verify_comment_meta_data( $commentdata ) {
if ( ! isset( $_POST['rating'] ) )
wp_die( __( 'Error: You did not add a rating. Hit the Back button on your Web browser and resubmit your comment with a rating.' ) );
return $commentdata;
}
Now we have our additional input fields in the comment form. We will use the following function to retrieve the comment’s meta data:
get_comment_meta( $comment_id, $meta_key, $single = false )
If we had been working with a theme, then all of the codes above would have gone into the functions.php file, and the code below would have been included in the comment template. Because we are creating a plugin, we will modify the comment’s output and inject our meta data into it. To do this, we’ll make use of the comment_text filter. In the code below, we first retrieve the URL of the plugin’s folder, which is required only because we will be using images saved in that folder (if we were using the codes in a theme, it would have been the URL of the style sheet’s directory or the theme’s directory).
Depending on whether the comment data is set, we might have to retrieve the comment data and text and then add them to the comment section, with the desired formatting. In the code below, the comment’s title is appended to the beginning of the comment’s text, while the rating images and value are added at the end.
// Add the comment meta (saved earlier) to the comment text
// You can also output the comment meta values directly to the comments template
add_filter( 'comment_text', 'modify_comment');
function modify_comment( $text ){
$plugin_url_path = WP_PLUGIN_URL;
if( $commenttitle = get_comment_meta( get_comment_ID(), 'title', true ) ) {
$commenttitle = '<strong>' . esc_attr( $commenttitle ) . '</strong><br/>';
$text = $commenttitle . $text;
}
if( $commentrating = get_comment_meta( get_comment_ID(), 'rating', true ) ) {
$commentrating = '<p class="comment-rating"> <img src="'. $plugin_url_path .
'/ExtendComment/images/'. $commentrating . 'star.gif"/><br/>Rating: <strong>'. $commentrating .' / 5</strong></p>';
$text = $text . $commentrating;
return $text;
} else {
return $text;
}
}
Now, our plugin is ready for us to add the desired input fields in the comment form and to display the meta data with comments. We could stop here, but we won’t. WordPress allows us to edit comments, and we want the option to edit the information entered in these meta fields as well. Therefore, we will continue coding our plugin and add an option to edit these meta fields from the comment editing screen.
We’ll add a meta box on the comment editing page using the add_meta_boxes_comment hook, which tells WordPress to add the reference meta box to the comment editing page. In the function, we’ll add a meta box using the add_meta_box function, the details of which you can check in the WordPress Codex.
add_meta_box( $id, $title, $callback, $post_type, $context, $priority, $callback_args );
We’re using the meta boxes to add the form fields, along with a wp_nonce_field for security. In the callback function, we retrieve the meta data before proceeding. We then recreate the same set of input fields as were added in the comment form; the only difference is that here, we also show the value. For the rating radio field, we have again used a simple loop; this time checking whether the radio should be checked comes in handy. Using the resulting input fields, we can now modify the meta data added to comments.
// Add an edit option to comment editing screen
add_action( 'add_meta_boxes_comment', 'extend_comment_add_meta_box' );
function extend_comment_add_meta_box() {
add_meta_box( 'title', __( 'Comment Metadata - Extend Comment' ), 'extend_comment_meta_box', 'comment', 'normal', 'high' );
}
function extend_comment_meta_box ( $comment ) {
$phone = get_comment_meta( $comment->comment_ID, 'phone', true );
$title = get_comment_meta( $comment->comment_ID, 'title', true );
$rating = get_comment_meta( $comment->comment_ID, 'rating', true );
wp_nonce_field( 'extend_comment_update', 'extend_comment_update', false );
?>
<p>
<label for="phone"><?php _e( 'Phone' ); ?></label>
<input type="text" name="phone" value="<?php echo esc_attr( $phone ); ?>" class="widefat" />
</p>
<p>
<label for="title"><?php _e( 'Comment Title' ); ?></label>
<input type="text" name="title" value="<?php echo esc_attr( $title ); ?>" class="widefat" />
</p>
<p>
<label for="rating"><?php _e( 'Rating: ' ); ?></label>
<span class="commentratingbox">
<?php for( $i=1; $i <= 5; $i++ ) {
echo '<span class="commentrating"><input type="radio" name="rating" id="rating" value="'. $i .'"';
if ( $rating == $i ) echo ' checked="checked"';
echo ' />'. $i .' </span>';
}
?>
</span>
</p>
<?php
}
As our last step, we need to devise a mechanism for saving the modified data from the editing screen. This is quite similar to the process for saving the meta data from a comment form. Here, we use the edit_comment function to verify the nonce key, and then we update or delete the comment meta field.
// Update comment meta data from comment editing screen
add_action( 'edit_comment', 'extend_comment_edit_metafields' );
function extend_comment_edit_metafields( $comment_id ) {
if( ! isset( $_POST['extend_comment_update'] ) || ! wp_verify_nonce( $_POST['extend_comment_update'], 'extend_comment_update' ) ) return;
if ( ( isset( $_POST['phone'] ) ) && ( $_POST['phone'] != '') ) :
$phone = wp_filter_nohtml_kses($_POST['phone']);
update_comment_meta( $comment_id, 'phone', $phone );
else :
delete_comment_meta( $comment_id, 'phone');
endif;
if ( ( isset( $_POST['title'] ) ) && ( $_POST['title'] != '') ):
$title = wp_filter_nohtml_kses($_POST['title']);
update_comment_meta( $comment_id, 'title', $title );
else :
delete_comment_meta( $comment_id, 'title');
endif;
if ( ( isset( $_POST['rating'] ) ) && ( $_POST['rating'] != '') ):
$rating = wp_filter_nohtml_kses($_POST['rating']);
update_comment_meta( $comment_id, 'rating', $rating );
else :
delete_comment_meta( $comment_id, 'rating');
endif;
}
Our plugin is still missing one critical thing: the ability to automatically delete the meta data for comments should we need to remove the plugin. We can easily instruct WordPress to delete all of the custom comment meta data with a small snippet of code. We just need to create a new file, uninstall.php, in the same folder as our plugin’s file and add the code below to it. This code will first check whether the plugin’s uninstall command is set to true. If so, it retrieves all of the comments and runs a foreach loop to delete the three meta fields. The uninstall command is initiated only when you delete the plugin through WordPress’ dashboard.
<?php
if( !defined( 'ABSPATH') && !defined('WP_UNINSTALL_PLUGIN') )
exit();
$comments = get_comments();
foreach($comments as $comment) {
delete_comment_meta($comment->comment_ID, 'phone');
delete_comment_meta($comment->comment_ID, 'title');
delete_comment_meta($comment->comment_ID, 'rating');
}
Download the Extend Comment WordPress Plugin

Screenshot of the Extend Comment plugin installed on the default WordPress theme
Conclusion
You can find a rating system implemented in the comments area of hosting review pages on Web Hosting Rock. It was added directly to the theme to allow for some flexibility and control over the ratings in user comments. We’ve now learned how to use custom meta fields to modify and extend the comment forms in WordPress posts, pages and custom posts. We’ve made use of conditional tags for greater control and customization. And we can restrict these custom fields to certain post types by forcing the functions that add custom input fields to be executed only if the “post type” conditions are met. Now, your comment forms need not be so boring. Add this extra element of fun and interactivity.
(al)





Louis-Philippe Dea
May 11th, 2012 2:35 pmAwesome tutorial, I was just looking on how to create a custom Required field. Thx!
alban
May 12th, 2012 12:46 pmreally a great tutorial
Andrew Gibson
May 17th, 2012 12:00 pmWith the radio buttons, would there be an easy way to add a class to the comment based on each of the potential responses? ex. attach class=”1Rating” to the comments and then when displaying the comments you have css for #comments.1Rating so that each rating might display slightly differently(for example background image or color to designate each)?
Pritam @ Specky Geek
May 27th, 2012 10:28 pmIt should be fairly easy to do if you implement the same in the comments.php template file. You just need to retrieve the rating value and use it as a class for comments.
If you want the plugin to handle it, you can use comment_class (http://codex.wordpress.org/Function_Reference/comment_class).
The following is a modified code based on how a class is added to the body. Not tested. Add it to the plug-in file and see if it works.
/**
* Adds classes to the array of comment classes
*/
function my_comment_class( $myclass ) {
if( $commentrating = get_comment_meta( get_comment_ID(), 'rating', true ) ) {
$myclass = $commentrating;
return $myclass;
}
add_filter( 'comment_class', 'my_comment_class' );
wassimo
May 26th, 2012 9:11 pmnice plugins really , so please
how to show count comment for ech rate , for example,
rate 1 : 5 rates ,
rate 2 : 8 rates ;
rate 3 : 1 rates ;
rate 4 : 2;
rates 5 : 0 rates ;
and thanks
Dino
June 5th, 2012 12:02 amFirst of all, this is an awesome plugin and awesome tutorial. I managed to incorporate it on the experimental theme that I am currently working on. However, I think I want to show the average rating. Is that possible? If so, can anybody here show me how?
Update: Nevermind, I have found the solution. Thanks for this wonderful post.
Sabrina
June 17th, 2012 11:29 amHI, what was the solution?
PH
June 10th, 2012 10:11 pmHi, I downloaded, installed, and activated the extend comment plugin, but I only got a comment title box, a rating section, and a large text area box labeled as comment. There is no field for phone number? What could be causing the phone field to not appear?
thanks,
ph
PH
June 10th, 2012 10:19 pmI didn’t see my last comment posted until I posted another message. Did it go though?
Sabrina
June 19th, 2012 3:01 amHow can i show more rating fields? i have 5 ratings… but there is only one showing.
Nate
July 10th, 2012 11:26 amFirst off,
Thanks for the plug-in! It’s great. It does exactly what I need.
The problem I am having is that I only want to have the different fields on a certain page. Its sort of like a classifieds section which requires more information than just Name and Email. This plugin allows me to add the necessary fields, but it adds them to EVERY page where comments are allowed. Is there anyway to limit where the new fields show up on a per page basis?
I’ve tried using the is_page(); function, but it does not do the trick.
Nate
July 11th, 2012 6:07 amFigured it out.
Louis-Philippe Dea
July 21st, 2012 9:10 amHi Nate, could you post your solution ? Thx!
jane
February 21st, 2013 11:00 pmArgh and this blog doesn’t allow links to websites, so I can’t go try to figure it out myself :(
talha hanjra
July 12th, 2012 12:01 amSir i am getting problem in saving and displaying custom fields data .
Can anyone tell where is data of custom fields like phone is saving.Thanks
Pranjal
July 16th, 2012 9:13 amGreat tutorial but, why does it simply prints “Comment Title,” if the comment title left emptied? it should simply hide that comment title when, the comment is moderated.
Muhammad Akseer
July 26th, 2012 12:10 amHi I love this plugin , i use it .
Thank you
Kevin
August 9th, 2012 10:28 amI’ve downloaded and installed the plugin but the extra fields are not showing up on the comment form on the post. However, the fields are there in the admin section when I click edit a comment. Please advise.
Saad
August 17th, 2012 8:06 amplugin does not work for me. i get this message while submitting a comment “You have taken too long. Please go back and refresh the page”
Jack
August 26th, 2012 11:45 amI see a couple of people have already asked this BUT, how can I display the average rating on my site?
P.S thanks for the awesome tut.
Luciano A. Ferrer
September 26th, 2012 6:18 pmWow, really nice plugin…
One question… there is any way to show information only on the backend, and not the frontend?
I have tried commenting a few lines at the modify_comment section, but that affects frontend and backend visualization…
Any idea?
Luciano A. Ferrer
October 1st, 2012 6:10 pmOk, I asked for a way to go (read at least) on the wordpress IRC channel, someone pointed me to: http://codex.wordpress.org/Function_Reference/current_user_can
Then used a few codes on function modify_comment( $text ) section
It works!
Thomas
October 12th, 2012 1:25 amThis and jQuery Star Rating would make a pretty couple
http://www.fyneworks.com/jquery/star-rating/
Zul
March 23rd, 2013 6:57 pm‘We’ often becomes ‘me’ in times of perosnal triumph.Then the me becomes we when that triumph is either diluted or it soon becomes less of a success. It’s human nature.VA:F [1.9.6_1107]please wait…VA:F [1.9.6_1107](from 0 votes)
Faiz
October 22nd, 2012 1:21 amIm trying to add a default value for a custom field whenever the user is already log in..I’ve tried registering the metadata with an if statement but doesn’t seem to work. Any ideas?
owen
November 12th, 2012 2:09 amIs there a way to use this and add a filter for the results to only show, 3 star comments, and then only 4 star comments, etc..
Chris
December 14th, 2012 2:52 pmI appreciate the tutorial, as this is exactly what I need for configuring comments for a custom post type. One question: the plugin as used (with WP 3.5) gives the following error when a comment is submitted: “You have taken too long. Please go back and refresh the page.” Any ideas what would cause this?
Ant
January 15th, 2013 7:13 amI am also recieving the message “You have taken too long. Please go back and refresh the page.” which appears to be related to 3.5,if anyone could help, this is the only working verison of a rating system i’ve been able to get to work properly
Piyush
January 31st, 2013 8:13 pmThis Plugin will solve your problem
http://www.thewebexpert.in/email-notification-on-comment-approval-in-wordpress/
Marcus
February 10th, 2013 3:53 pmSounds like a great plugin and exactly what I’m looking for, but unfortunately when I tried to upload it I got the following message:
PCLZIP_ERR_BAD_FORMAT (-10) : Unable to find End of Central Dir Record signature
Can you please help me out?
Mike G
March 20th, 2013 1:35 pmI am using the post comment form as a contact form (Learn More) for a law firm.
These instructions are great. However when I put the folder and file in my plugins it does not activate.
Any ideas as to what I have done wrong?
Thanks,
Constantin
March 27th, 2013 5:22 amI want to add multiple ratings.
I’ve managed to add the in leave a reply, but they don’t show up in the cooment text box above
Constantin
March 27th, 2013 5:41 amFound out how:
function modify_comment( $text )
does a return $text after the first if, and to work i’ve commented those returns and made only one after all the $text has been written
Mwea
April 11th, 2013 11:27 amHey, I just made this plugin to add custom comment fields, and change the comment field titles… hope it helps!
http://codecanyon.net/item/custom-comment-field-creator-wp-plugin/4498472?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Mwea
See a video preview here :
http://www.youtube.com/watch?v=uheyynP1dqY
sun
May 7th, 2013 5:45 pmThis post truly deserves a medal. Thanks a ton!
Saved me hours (or even days?) of introspecting and debugging WordPress’ very odd (hook) architecture. That said, it’s probably wrong to mention “WordPress” and “architecture” in the same sentence in the first place though.
While I can understand that its UI is working out fairly well, I’m still flabbergasted about the huge user base and adoption of WordPress. If someone would apply for a PHP related job and was showing such code as a sample, that application would move straight to the trash bin.
How PHP is supposed to be used today:
http://phptherightway.com
(not affiliated with that, but it certainly cuts the basics)
What wasn’t mentioned in this post:
The WordPress core bootstrap manually applies PHP’s deprecated and discontinued magic_quotes_gpc to all user input – replacing all original PHP superglobals, without providing a backup somewhere. Essentially: addslashes() on all server parameters.
So in case you need to work with the original user input without bogus munging, you might be able to use WP’s stripslashes_deep() helper function, which performs the reverse of the addslashes() operation.
However, be careful when doing so: The entire security of WP core + plugins depends on this gem! (effectively magic_quotes) — Do not strip slashes from the original, shared superglobals (e.g., $_POST). Only from local array copies.
Anyway, this excellent tutorial (+ code examples) allowed me to move forward with a relatively complex WordPress plugin much faster than I originally planned.
Thanks!
sun