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:
[php]
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;
}
}
[/php]
That modular code can be accessed by our AJAX function:
[php]
function ajax_commentcallout () {
if ( ! current_user_can( ‘moderate_comments’ ) ) die(‘-1′);
$commentid = intval( $_POST['commentid'] );
if ( $commentid ) {
if ( curate_comment( $commentid ) ) {
die(‘1′);
}
}
}
add_action( ‘wp_ajax_comment_callout’, ‘ajax_commentcallout’ );
[/php]
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:
[javascript]
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 );
break;
}
}
});
return found;
}
[/javascript]
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:
[php]
<span class="callouton callout-12345">Call Out</span>
[/php]
With this code:
[php]
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>
<?php
}
}
[/php]
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:
[css]
.curated {
background-color: #E0FFE0;
}
[/css]
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:
[php]
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 );
[/php]
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.
[php]
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;
}
[/php]
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:
[php]
do_action( ‘curate_comment’, $comment_id );
[/php]
To do something when the comment is called out:
[php]
function curate_notify( $comment_id ) {
// do something using $comment_id
}
add_action( ‘curate_comment’, ‘curate_notify’, 20, 1 );
[/php]
Post Your Comment
You must be logged in to post a comment
T/S Members
Log in with your True/Slant account.









[...] Continue reading here: Curating and filtering blog post comments with WordPress and AJAX [...]
[...] why this field was important to WordPress. Today, I stumbled across an article on True/Slant that explains their use of this particular field with AJAX to curate and filter comments. They provide the code snippets [...]
[...] Read more: Curating and filtering blog post comments with WordPress and AJAX – Roger Theriault – In… [...]
What about updating the object cache for that comment after boosting its karma?
Thanks Mark. We haven’t (yet) run into any issues with that. But I assume we’d want to add this line after the $wpdb->update and before the do_action(), to invalidate the cache and avoid the cache clobbering our update:
clean_comment_cache($comment_id);
In response to another comment. See in context »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.
Yes functions.php will work. Keep in mind you’ll need to put the css and js portions in different places, or create a hook to insert them in the site header and footer respectively. Rename your functions so they don’t collide with some plugin’s functions (eg append “my_” or something to them; I used very generic function names only as examples).
And you will also need to modify your comment template to call ppi_curate_comment_link, see the WordPress Codex for info on wp_list_comments and some code examples here and here.
In response to another comment. See in context »Well, I’m struggling with the ‘Walker class’ function reference at the moment… but will press on as best I can. Again, thanks!
In response to another comment. See in context »[...] Curating and filtering blog post comments with WordPress and AJAX [...]
Are you going to patent “a mechanism for the allocation of karma among blog comments”?