That sounds like a useful feature. To get what you need you have to change three things:
- Add a checkbox to enable anonymous comments per post.
- Save the checkbox value together with the post.
- Filter the checks for the comment registration requirement on the post views to enable the comment form and on the actual comment save action to let them go through.
The checkbox
If you open the Screen Options on a post editor page you can enable the Discussion metabox. We will add our checkbox to that metabox:
We are lucky, there is a hook: 'post_comment_status_meta_box-options'
. Let’s use it:
add_action( 'post_comment_status_meta_box-options', 'acpp_checkbox' );
/**
* Print a checkbox into the comment status metabox.
*
* @wp-hook post_comment_status_meta_box-options
* @param object $post
* @return void
*/
function acpp_checkbox( $post )
{
$key = '_allow_anonymous_comments';
$current = get_post_meta( $post->ID, $key, TRUE );
printf(
'<br /><label for="%1$s">
<input type="checkbox" id="%1$s" name="%1$s" class="selectit" %2$s/> %3$s
</label>',
$key,
checked( 1, $current, FALSE ),
apply_filters( 'acpp_metabox_label', 'Allow anonymous comments.' )
);
}
As you can see, I invented a new post meta key '_allow_anonymous_comments'
. The leading underscore will hide it from the Custom Fields metabox. (Related: How to delete custom field “suggestions” from dropdown list)
If the meta value exists already and if it is equal to 1
we preselect it.
The filter 'acpp_metabox_label'
exists to allow theme authors translating that value. I was too lazy to add a language file for just one tiny string …
Save the meta value
To save our value we hook into 'save_post'
, run some checks and store the result as an integer:
add_action( 'save_post', 'acpp_save' );
/**
* Save the checkbox value as number
*
* @wp-hook save_post
* @param int $post_id
* @param object $post
* @return void
*/
function acpp_save( $post_id, $post )
{
// AJAX autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
// Some other POST request
if ( ! isset ( $_POST['post_type'] ) )
return;
// Missing capability
if ( ! current_user_can( 'edit_' . $_POST['post_type'], $post_id ) )
return;
$key = '_allow_anonymous_comments';
// Checkbox successfully clicked
if ( isset ( $_POST[ $key ] ) and 'on' === strtolower( $_POST[ $key ] ) )
return update_post_meta( $post_id, $key, 1 );
// Checkbox deselected
delete_post_meta( $post_id, $key );
}
Filter registration checks
And now we have to use that value on the front-end and change the result for checks on the option comment_registration
. We don’t want to change the blog wide value in wp-admin
:
That’s why we add a check for is_admin()
to that filter. Filtering option checks is actually simple: Hook into 'pre_option_' . $option_name
and return any other value than FALSE
. Since we do not want to return TRUE
either, we trick that check by returning 0
.
add_filter( 'pre_option_comment_registration', 'acpp_comment_reg_filter' );
/**
* Trick the registration checks on front-end
*
* Important: If we return FALSE, the filter will be effectively ignored.
* It has to be any other value.
*
* @wp-hook pre_option_comment_registration
* @return bool|int
*/
function acpp_comment_reg_filter()
{
if ( is_admin() )
return FALSE;
$key = '_allow_anonymous_comments';
$post_id = 0;
// Only available on wp-comments-post.php, not on regular post pages.
if ( isset( $_POST['comment_post_ID'] ) )
$post_id = (int) $_POST['comment_post_ID'];
//
$post = get_post( $post_id );
$open = get_post_meta( $post->ID, $key, TRUE );
if ( 1 == $open )
return 0;
return FALSE;
}
This check is used by WordPress for the comment form, the comment reply links on threaded comments and when a comment is saved in wp-comments-post.php
.
Plugin
That’s all. You can download the code as a plugin on GitHub:
Plugin Anonymous comments per post