1. Turn comments off in Settings → Discussion
Recommended: auto-close after 0 days
This one setting closes comments on every existing post and page as soon as the front end loads. The default article settings cover new content and trackbacks.
- Log in to the WordPress dashboard.
- Go to Settings → Discussion.
- Under Default article settings:
- Uncheck “Allow people to submit comments on new articles”.
- Uncheck “Allow link notifications from other blogs (pingbacks and trackbacks) on new articles”.
- Under Other comment settings:
- Check Automatically close comments on articles older than.
- Set the number to 0 days.
- Click Save Changes.
What this does:
- New posts and pages will not allow comments or trackbacks.
- Existing content is treated as closed on every page load. WordPress checks the 0-day rule dynamically, so you do not wait on a cron job or a bulk edit.
- Trackbacks and pingbacks are blocked on future content. The code in section 2 also forces existing pings closed.
Optional: write closed status into the database
Use this when you want comment_status = 'closed' and ping_status = 'closed' stored on every post. That helps on very large sites, or if a theme or plugin reads the raw post fields instead of comments_open(). Skip it for a typical site. The 0-day setting already closes comments on the front end.
- Go to Posts → All Posts. Repeat later for Pages and any custom post types that support comments.
- Open Screen Options and raise items per page (for example, 200).
- Select all items → Bulk actions → Edit → Apply.
- Set Comments to Do not allow.
- Set Pings to Do not allow.
- Click Update.
2. Permanent kill-switch (must-use plugin)
Add this after the Discussion settings. It overrides comment and trackback behavior even if someone later changes the 0-day setting, and it covers cases the Discussion screen cannot (admin UI, direct POSTs to wp-comments-post.php, leftover comments in the database).
Where to add it: create wp-content/mu-plugins/tinyfrog-disable-comments.php. A must-use plugin stays active even if the theme changes. You can paste the same functions into a child theme functions.php instead, but the MU plugin is the better home.
<?php
/**
* Plugin Name: Tiny Frog Disable Comments
* Description: Completely disable comments and trackbacks site-wide.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* 1. Remove comment and trackback support from every post type.
*/
function tinyfrog_disable_comments_post_type_support() {
$post_types = get_post_types( array(), 'names' );
foreach ( $post_types as $post_type ) {
if ( post_type_supports( $post_type, 'comments' ) ) {
remove_post_type_support( $post_type, 'comments' );
}
if ( post_type_supports( $post_type, 'trackbacks' ) ) {
remove_post_type_support( $post_type, 'trackbacks' );
}
}
}
add_action( 'admin_init', 'tinyfrog_disable_comments_post_type_support' );
/**
* 2. Force comments and pings closed (covers the 0-day setting and theme/plugin attempts).
*/
function tinyfrog_disable_comments_status( $open, $post_id ) {
return false;
}
add_filter( 'comments_open', 'tinyfrog_disable_comments_status', 20, 2 );
add_filter( 'pings_open', 'tinyfrog_disable_comments_status', 20, 2 );
/**
* 3. Hide existing comments on the front end. Rows stay in the database.
*/
function tinyfrog_disable_comments_hide_existing( $comments ) {
return array();
}
add_filter( 'comments_array', 'tinyfrog_disable_comments_hide_existing', 10, 2 );
/**
* 4. Remove Comments from wp-admin.
*/
function tinyfrog_disable_comments_admin_cleanup() {
remove_menu_page( 'edit-comments.php' );
global $pagenow;
if ( 'edit-comments.php' === $pagenow ) {
wp_safe_redirect( admin_url() );
exit;
}
remove_meta_box( 'dashboard_recent_comments', 'dashboard', 'normal' );
if ( is_admin_bar_showing() ) {
remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 60 );
}
}
add_action( 'admin_menu', 'tinyfrog_disable_comments_admin_cleanup', 999 );
add_action( 'admin_init', 'tinyfrog_disable_comments_admin_cleanup' );
add_action( 'init', 'tinyfrog_disable_comments_admin_cleanup' );
/**
* 5. Block direct POST submissions to wp-comments-post.php.
*/
function tinyfrog_block_comment_post() {
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';
if ( isset( $_POST['comment_post_ID'] ) || false !== strpos( $request_uri, 'wp-comments-post.php' ) ) {
wp_die(
'Comments are disabled on this site.',
'Comments Disabled',
array( 'response' => 410 )
);
}
}
add_action( 'init', 'tinyfrog_block_comment_post' );
What the code does
| Part | Effect |
|---|---|
| 1. Post type support | Removes the comment and trackback features from every post type in wp-admin. |
2. comments_open / pings_open | Returns false on every request, including existing content and the 0-day setting. |
| 3. Hide existing comments | Front end shows no old comments. Nothing is deleted from the database. |
| 4. Admin cleanup | Removes the Comments menu, the dashboard widget, and the admin-bar comments icon. Visiting edit-comments.php redirects to the dashboard. |
| 5. Block POST | A direct submit to wp-comments-post.php gets a 410 response instead of inserting a comment. |
Safe to leave in place. It is idempotent: running it on a site that already has comments closed does not hurt anything.
3. Optional WP-CLI database update
For a large site, bulk-edit in wp-admin is slow. After the Discussion settings and the MU plugin, you can write closed status to every post and page with:
wp post update $(wp post list --post_type=post,page --format=ids) --comment_status=closed --ping_status=closed
Add other post type slugs to --post_type= if the site has custom types that still show open in the database. This is optional. The 0-day setting plus the kill-switch already stop submissions.
4. Confirm it worked
- View a post or page on the front end. There should be no comment form and no trackback / pingback UI.
- In wp-admin, Settings → Discussion should still show comments and pingbacks unchecked, and auto-close set to 0 days.
- With the MU plugin in place, the Comments item should be gone from the left admin menu and from the admin bar.
- Optional: POST to
/wp-comments-post.php. You should get a 410 “Comments Disabled” response, not a new comment in the database.
Existing comments stay in the database. They are hidden and cannot accept replies.