What Is True/Slant?
275+ knowledgeable contributors.
Reporting and insight on news of the moment.
Follow them and join the news conversation.

Feb. 26 2010 - 12:20 pm | 338 views | 1 recommendation | 10 comments

Curating and filtering blog post comments with WordPress and AJAX

Whether to allow comments on a post can be a controversial subject – if you allow them, they can turn into a mess of irrelevance, or worse. On the other hand, comments can promote engagement, conversations, and add value to the story. Especially when the discussion is civil and relevant to the topic of the post.

One way to make user comments a bit more effective and relevant is to use thumbs up or down voting buttons, either rating the commenter or the comment. This is user-driven moderation, and while it sounds good in principle, sometimes it is seen as a device for voting down opposing viewpoints, which doesn’t necessarily improve a discussion.

Here on True/Slant, member comments are curated by contributors and editors. Good, relevant comments are typically the ones that get called out; comments that don’t contribute to the conversation are not. Comment threads are by default filtered by this rating, but users can switch to an all-comments view.

So how does this comment curation work, technically?

Generally, we expose a control to only the contributors; when they click on the control, an AJAX request is sent, the database is updated, and the response causes the current comment’s class to change. CSS does the rest. Here’s the code…

We decided to use the field “comment_karma” to track curated comments. It’s already there in the comments table, ready for us to use (provided, of course, we’re not using another plugin that’s using that field in a different way).

To curate a comment, we just set comment_karma to 1:

function curate_comment( $comment_id ) {
// set this comment to curated
global $wpdb;
$comment_id = intval( $comment_id );
if (wpdb->update( ‘comments’, array( ‘comment_karma’ => ‘1′ ), array( ‘comment_ID’ => $comment_id ), array( ‘%s’ ), array( ‘%d’ ) )) {
do_action( ‘curate_comment’, $comment_id );
return true;
} else {
return false;

That modular code can be accessed by our AJAX function:

function ajax_commentcallout () {
if ( ! current_user_can( ‘moderate_comments’ ) ) die(‘-1′);
$commentid = intval( $_POST['commentid'] );
if ( $commentid ) {
if ( curate_comment( $commentid ) ) {
add_action( ‘wp_ajax_comment_callout’, ‘ajax_commentcallout’ );

This code only works if the current user is a comment moderator.

The add_action hooks our function into the WP AJAX handler. Our action name is the text following wp_ajax_, eg: comment_callout.

To trigger the AJAX, we need a bit of JavaScript – we’ll use jQuery:

jQuery( document ).ready( function() {
jQuery( ‘.callouton’ ).click( function() {
callout_on( this );
return false;
} );

function callout_on(sel) {
var commentid = getClassId( sel, ‘callout-’ );
jQuery.post( ajaxurl,
{ action: "comment_callout",
commentid: commentid
}, function(data) {
if (data == ‘1′) {
jQuery( ‘#comment-’+commentid ).addClass( ‘curated’ );

function getClassId( selector, cssclass ) {
var found = 0;
jQuery(selector).filter( function () {
var classes = jQuery( this ).attr( "className" ).split(" ");
for (var i = 0; i > classes.length; i++) {
if ( classes[i].substr( 0, cssclass.length ) == cssclass ) {
found = classes[i].substr( cssclass.length );
return found;

How does this work? When you click on the element with class callouton, the function is called, it pulls the comment id out of another class in the same element, posts to the ajax handler with our action and the comment id, and then if it gets a 1 back, adds the curated class to the comment div. More details on AJAX in the WordPress Codex.

You just need to add this to each comment:
<span class="callouton callout-12345">Call Out</span>

With this code:
function ppi_curate_comment_link() {
if ( current_user_can( ‘moderate_comments’ ) ) {
global $comment;
<span title="Call out this comment" class="callouton callout-<?php echo $comment->comment_ID; ?>">Call Out</span>

Depending on your theme, you may need to add this to an existing custom Walker class, or create a new one.

How do we show a curated comment? We’ll leave that to you; this CSS will simply change the background color:

.curated {
background-color: #E0FFE0;

Now, this will be fine until the page reloads. To add the curated class to comments that have a comment_karma of 1, we need to filter the comment classes:

function filter_comment_class( $classes, $class = ”, $comment_id, $post_id = null ) {
if ( is_curated( $comment_id ) ) {
$classes[] = "curated";
return $classes;
add_filter( ‘comment_class’, ‘filter_comment_class’, 90, 4 );

Oh, what’s is_curated() ? It’s a utility function, so we keep our logic – whether we’re using comment_karma – in just a few places, curate_comment(), and is_curated(). If we need to change how we track comments, we only need to change those two functions.

function is_curated( $comment_id ) {
// return true if comment has been "Curated"
$comment =& get_comment( $comment_id );
if ( $comment && ( $comment->comment_karma > 0 ) ) {
return true;
return false;

That’s the simple implementation – a more advanced system would want to have an “off” button as well as expose the same functionality on the Admin comment manager interface.

Now, if you’ve ever had a comment called out here on True/Slant, you may have received an email notification. By adding the hook to the curate_comment() function, we can trigger other changes on the site whenever a comment is called out – such as sending an email to a member, adding the curated comment to the contributor’s activity feed, increasing a count of curated comments for the post, etc. All without needing to change our curation code.

This code is already in the curate_comment() function:
do_action( ‘curate_comment’, $comment_id );

To do something when the comment is called out:
function curate_notify( $comment_id ) {
// do something using $comment_id
add_action( ‘curate_comment’, ‘curate_notify’, 20, 1 );


4 T/S Member Comments Called Out, 10 Total Comments
Post your comment »
  1. collapse expand

    What about updating the object cache for that comment after boosting its karma?

  2. collapse expand

    This looks like such a beautifully lightweight solution. Sadly I can’t get it to work yet (at least, not by recreating in functions.php – maybe I’m in the wrong place…), but I will be trying!

    Exactly what I’m after right now – we similarly have a site where we would like admins to be able to ‘promote’ insightful comment, without exposing that facility to the whole community, which is what many of the existing plugins seem to do. Thanks so much for sharing it.

  3. collapse expand

    Are you going to patent “a mechanism for the allocation of karma among blog comments”? ;)

Log in for notification options
Comments RSS

Post Your Comment

You must be logged in to post a comment

Log in with your True/Slant account.

Previously logged in with Facebook?

Create an account to join True/Slant now.

Facebook users:
Create T/S account with Facebook

My T/S Activity Feed


    About Me

    I'm a software developer and a principal contributor to the technology development here at True/Slant.

    I develop the front and backend site features that make websites work, using PHP, jQuery, MySQL, CSS, XHTML, Javascript, Flash, and AJAX. I also work with WordPress MU and web APIs.

    In the past, I've done software application development and support, mobile solutions, and strategic business development. I worked at Motorola for over a decade. I have an MBA from the University of Miami, and a US Patent. And I've been a real estate agent and mortgage broker.

    Journalism isn't new to me, either - I've been a photographer, photo editor, and occasional writer for university weeklies. It's nice to bring all that together here on True/Slant.

    See my profile »
    Followers: 12
    Contributor Since: October 2008
    Location:Lantana, Florida