Custom Comment Fields in WordPress

On a recent project I needed to implement a products section. The products section needed a number of functional pieces that very closely aligned with that of built in Posts in WordPress. The site was already slated to have a blog, so hijacking Posts themselves was out of the question, but lead to the perfect application of a Custom Post Type.

There were some unique fields I needed to support some of the functionality of the Products section in its entirety, but in particular I was aiming to repurpose comments to support reviews. Changing a few labels got just about everything taken care of, but the client was looking to have a location field in addition to a name, email, and the review itself.

But… why not use Pods?

The short answer here is that Pods 2.0 isn’t out yet. Pods 2.0 would have made the need to build this additional functionality from the ground up unnecessary, flat out. Pods 2.0 is still under development, and with WordPress 3.1 RC3 available, we’re in high gear on getting things up and running. For the time being though, client work continues.

Reviews aren’t comments though

My strategy in building WordPress powered sites is to use anything and everything available in core before branching out to plugins. That includes manually writing queries, implementing my own hooks by hand, and generally resisting the need to use plugins wherever possible. I take this route because WordPress is a system in and of itself. To me it’s very important to build upon that system by taking advantage of what it’s got to offer.

In this particular case, I wanted the products section to be as searchable as possible, resulting in my decision to use a Custom Post Type. Additionally, WordPress’ comment system is great, why reinvent (and rewrite) the wheel? You actually have decent granular control over the comment experience, specifically when it comes to fields. What leaves a bit to be desired though, is the ability to use your own Custom Fields with comments. It’s not extensively documented, but there is database storage and core functionality for comment metadata built into WordPress as of version 2.9.

Continuing, while I do my best to use WordPress core functionality at all costs, I don’t stretch it. If something isn’t there, shoehorning is not a solution I default to either, I’ll build it in if a great plugin isn’t out there. When I do build additional functionality though, I do my best to see whether or not it would be useful to other developers. If the functionality is too unique, it’ll go into functions.php or a private plugin. There are times though, where the functionality is generic enough to be useful on a more global level. Many times I’ll build in the functionality, and it’s only when I can pull together the time I’ll refactor what needs to be taken care of and ideally push out a plugin for everyone to use. Custom comment fields happen to be such a case, in my opinion.

Doing it by hand

While this article is technically an overview of the inspiration behind the plugin, I’d like to walk through how it actually works in case you’d prefer to do it by hand. There isn’t a whole lot to it, so let’s begin.

The first part will be making sure the field ends up on the front end in the first place. To do that, we’re going to hook comment_form_default_fields and add our desired field, in this case we’ll be using Location.

function iti_review_fields($fields) { global $post; if( is_singular( 'iti_products' ) ) // this is our CPT { $fields['url'] = ''; $fields['location'] = '<p class="comment-form-location">' . '<label for="location">' . __( 'Location' ) . '</label> ' . '<input id="location" name="location" type="text" value="' . esc_attr( $commenter['location'] ) . '" size="30" /></p>'; $fields = array( $fields['author'], $fields['location'], $fields['email'], $fields['url'] ); } return $fields; } add_filter( 'comment_form_default_fields', 'iti_review_fields' );

Essentially what we’re doing here is appending a location key to the $fields array WordPress uses. That’s going to get our new comment field to show up on the front end, but only if we’re viewing our Custom Post Type named iti_products:

Awesome, our additional field has been set up, but the next issue to deal with is actually saving the submitted data. WordPress doesn’t accept dynamically submitted comment form fields (which is a good thing) so we’ll need to expressly accept that submitted data. This is easily accomplished with another hook, this time to comment_post:

function iti_add_author_location($comment_id) { add_comment_meta( $comment_id, 'location', $_POST['location'], true ); } add_action( 'comment_post', 'iti_add_author_location', 1 );

That snippet can also be added to functions.php and enables our newly created location comment field to be saved to wp_commentmeta.

The final step would be to modify the way your comments are listed on the front end via wp_list_comments() or otherwise. If using wp_list_comments() with a callback, you’ll need to edit your callback function and manually pull the data from wp_commentmeta — luckily WordPress makes this as easy as pulling post meta:

echo get_comment_meta( $comment->comment_ID, 'location' );

This process can be repeated for each additional comment field you’d like to use, and you can customize it on a per-CPT basis by using the is_singular() conditional. With this process being so simple but at the same time being tedious with the possibility of quickly bloating and becoming very non-DRY, it leaves great opportunity for a plugin.

Things to be aware of

While our fields appear fully implemented on the front end, we haven’t taken any steps to customize the display or editing of this data in such a way that’s provided with standard comments. There are a few steps to take here, but at this point they’re pretty much hacks and I’ll be researching how to better integrate the editing process.

Plugin Status

This plugin is no longer actively maintained by me and has been removed from the WordPress Plugin repository. You can replicate the functionality as outlined above and enhance it as you wish.