Problem:
A client needed just one page to have comments where the user must log in. The client wanted the rest of the pages to be open to anyone to comment. I found no such plugin.
Solution:
At first I was going to write a plugin, but being that I have never wrote an official plugin before I decided to go the simpler route. I ended up creating 3 template files and adding a function to the functions.php file. Since almost all pages will allow anonymous comments, the wordpress setting will allow comments. The following changes will prevent users from posting a comment to specific page-templates.
page-comment-restrict.php
This is a copy of page.php. the only difference is the loop part will call ‘page-comments-restrict’ instead of the ‘page’ template. Use this template for each page that needs the comments restricted.
loop-page-comment-restrict.php
This is a copy of loop-page.php. The only difference is the comment template. Instead of calling the default comment template it will call ‘/comments-restrict.php’.
comments_template( '/comments-restrict.php', true );
comments-restrict.php
This is a copy of the comments.php. The difference is you need to copy some login code from “/wp-includes/comment-template.php”. Specifically the part where it checks for comment_registration and is_user_logged_in. After making a copy of comments.php, replace comment_form() with the code below.
<?php if ( comments_open() ) : ?> <?php do_action( 'comment_form_before' ); ?> <div id="respond"> <h3 id="reply-title"><?php comment_form_title( 'Leave a Reply', 'Leave a Reply to %s' ); ?> <small><?php cancel_comment_reply_link( 'Cancel reply' ); ?></small></h3> <?php if ( !is_user_logged_in() ) : ?> <?php echo '<p>' . sprintf( __( 'You must be <a href="%s">logged in</a> to post a comment.' ), wp_login_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) ) ) . '</p>'; ?> <?php do_action( 'comment_form_must_log_in_after' ); ?> <?php else : comment_form(); endif; ?> <?php endif; ?>
functions.php
All the changes up until now are to hide the comments form on the page. However, a malicious user could still try to post a comment to your page because the wordpress setting is to allow anonymous comments. To prevent this, we need to catch all comments before it is posted by adding an action hook at ‘pre_comment_on_post’. Add the following code to the functions.php file.
if ( ! function_exists( 'comments_restrict' ) ) : /** * Restricts comments to logged in users only for the specific pages determined by page template. * */ function comments_restrict($post_ID) { $meta_value = get_post_meta($post_ID, '_wp_page_template', true); if ($meta_value == 'page-comments-restrict.php') { $user = wp_get_current_user(); if (!$user->ID) wp_die( __('Sorry, you must be logged in to post a comment.') ); } } endif; add_action('pre_comment_on_post', 'comments_restrict');
That’s it. It should restrict users who are not logged in from commenting. Test it out with the following steps:
- Replace the code in comments-restrict.php with the normal comments_form(); method. Try to post a comment. The result should be a page that says you need to be logged in.
- View the page with and without the wordpress setting to allow anonymous comments. You should see no difference.