How can I have sticky comments? I am trying to make it so that I can make a comment go above all the other comments. Is this possible? If so what code can I use to achieve this? Thanks
How can I have sticky comments? I am trying to make it so that I can make a comment go above all the other comments. Is this possible? If so what code can I use to achieve this? Thanks
Share Improve this question edited Oct 25, 2015 at 14:08 fuxia♦ 107k39 gold badges255 silver badges459 bronze badges asked Oct 25, 2015 at 3:42 matthewmatthew 4851 gold badge3 silver badges17 bronze badges1 Answer
Reset to default 8I was curious about any existing plugins and searched the plugin directory. There exists an old Sticky Comments plugin, I'm not related to it. It seems to use a sticky meta key.
It uses a LEFT JOIN query but creates it's own version of the whole comments_template()
core function, to override the current query. One would need to update that custom function, if the core function changes. This was most likely done because of the hard coded SQL queries that this function contained.
Now, in WordPress 4.3.1, the comments_template()
function only contains a single get_comments()
call and we can therefore use a single filter instead to override it.
Now here are few ideas how to do that:
Method #1
We could use the sticky comment type to mark the sticky comments.
Then we could use the pre_get_comments
hook to adjust the ordering:
add_action( 'pre_get_comments', 'wpse_comment_stickies_v1' );
function wpse_comment_stickies_v1( \WP_Comment_Query $q )
{
// Only run it once
remove_action( current_action(), __FUNCTION__ );
// Modify the ordering, so sticky comments are at the top
$q->query_vars[ 'orderby'] = [
'comment_type' => 'DESC',
'comment_date_gmt' => 'ASC',
'comment_ID' => 'ASC'
];
}
where you've to add the line:
add_action( 'pre_get_comments', 'wpse_comment_stickies_v1' );
just before the comments_template()
call in your theme.
The array ordering was added in WordPress 4.2 but the Codex on WP_Comment_Query
doesn't mention it.
Method #2
This one is similar as in #1, but here we use the comments_clauses
filter to modify the ordering of the comments:
add_filter( 'comments_clauses', 'wpse_comment_stickies_v2' );
function wpse_comment_stickies_v2( $clauses )
{
global $wpdb;
// Only run it once
remove_filter( current_filter(), __FUNCTION__ );
// Modify the ordering, so sticky comments are at the top
$clauses['orderby'] = $wpdb->comments . 'ment_type DESC, ' . $clauses['orderby'];
return $clauses;
}
Method #3
We could use the comment meta as well. If we mark the sticky comments with the sticky
comment meta, then we can modify the ordering with:
add_action( 'comments_clauses', 'wpse_stickies_v3' );
function wpse_stickies_v3( $clauses )
{
global $wpdb;
// LEFT JOIN the comments table and the comments meta table
$clauses['join'] .= "
LEFT JOIN {$wpdb->commentmeta} wpsecm
ON ( wpsecmment_id = {$wpdb->comments}ment_ID AND wpsecm.meta_key = 'sticky' ) ";
// Order by the meta key
$clauses['orderby'] = 'wpsecm.meta_key DESC, ' . $clauses['orderby'];
return $clauses;
}
Method #4
This is similar to #3, but where we only modify the orderby
clause:
add_action( 'comments_clauses', 'wpse_stickies_v4' );
function wpse_stickies_v4( $clauses )
{
global $wpdb;
$orderby = [];
$orderby[] = "
( SELECT COUNT( comment_ID )
FROM {$wpdb->commentmeta} wpsecm
WHERE wpsecmment_id = {$wpdb->comments}ment_ID
AND wpsecm.meta_key = 'sticky'
) DESC ";
$orderby[] = $clauses['orderby'];
$clauses['orderby'] = join( ',', $orderby );
return $clauses;
}
Notes
Sometimes I wish there was an argument filter in comments template()
, to make it easier to only target it's query, because you don't want to mess with other get_comments()
calls e.g. in the widgets.
I created a ticket #34442 with some suggestions, that would make it easier to target this query from a plugin.
In WordPress 4.4 the get_comments()
call will be replaced with:
$comment_query = new WP_Comment_Query( $comment_args );
but that will not change much here, since get_comments()
is just a simple WP_Comment_Query
wrapper.
I haven't mentioned here how one could modify the UI to mark the sticky comments. But you can e.g. check out this old plugin, I mentioned earlier, for ideas on that matter.