Users can extend WordPress functions by using this platform, which allows developers to expand its capabilities. in countless ways. One powerful feature is the ability to perform bulk actions on posts, pages, users, and other content types. While WordPress provides default bulk actions like “Delete” or “Edit,” you can create custom bulk actions tailored to your specific needs. This guide will walk you through the process of adding custom bulk actions to post and user listing screens, handling those actions securely, and providing feedback to users.
Bulk actions allow administrators to perform operations on multiple items (e.g., posts, users, comments) simultaneously. For example, you can delete 50 posts at once or change the status of 100 users from “Pending” to “Active.”

Before diving into code, ensure you have the following:
WordPress uses the bulk_actions-{screen_id} filter to modify bulk actions for specific screens. For posts, the screen ID is edit-post.
Example: Adding “Approve” and “Reject” Actions
add_filter('bulk_actions-edit-post', 'add_custom_post_bulk_actions');
function add_custom_post_bulk_actions($actions) {
$actions['approve'] = __('Approve', 'textdomain');
$actions['reject'] = __('Reject', 'textdomain');
return $actions;
}
Explanation
For the user listing screen, use the bulk_actions-users filter.
Example: Adding “Activate” and “Deactivate” Actions
add_filter('bulk_actions-users', 'add_custom_user_bulk_actions');
function add_custom_user_bulk_actions($actions) {
$actions['activate'] = __('Activate Users', 'textdomain');
$actions['deactivate'] = __('Deactivate Users', 'textdomain');
return $actions;
}
After adding bulk actions, you need to process them. Use the handle_bulk_actions-{screen_id} action hook.
Example: Approving or Rejecting Posts
add_action('handle_bulk_actions-edit-post', 'handle_post_bulk_actions', 10, 3);
function handle_post_bulk_actions($redirect_to, $action, $post_ids) {
if ($action === 'approve') {
foreach ($post_ids as $post_id) {
wp_update_post(array(
'ID' => $post_id,
'post_status' => 'publish'
));
}
$redirect_to = add_query_arg('approved', count($post_ids), $redirect_to);
} elseif ($action === 'reject') {
foreach ($post_ids as $post_id) {
wp_trash_post($post_id);
}
$redirect_to = add_query_arg('rejected', count($post_ids), $redirect_to);
}
return $redirect_to;
}
Explanation
Example: Activating or Deactivating Users
add_action('handle_bulk_actions-users', 'handle_user_bulk_actions', 10, 3);
function handle_user_bulk_actions($redirect_to, $action, $user_ids) {
if ($action === 'activate') {
foreach ($user_ids as $user_id) {
$user = new WP_User($user_id);
$user->set_role('subscriber');
}
$redirect_to = add_query_arg('activated', count($user_ids), $redirect_to);
} elseif ($action === 'deactivate') {
foreach ($user_ids as $user_id) {
$user = new WP_User($user_id);
$user->remove_role('subscriber');
}
$redirect_to = add_query_arg('deactivated', count($user_ids), $redirect_to);
}
return $redirect_to;
}
After processing bulk actions, display success or error messages using the admin_notices hook.
Example: Post Action Notices
add_action('admin_notices', 'show_post_bulk_action_notices');
function show_post_bulk_action_notices() {
if (!empty($_GET['approved'])) {
$count = intval($_GET['approved']);
echo '<div class="notice notice-success"><p>' . sprintf(__('%d posts approved.', 'textdomain'), $count) . '</p></div>';
}
if (!empty($_GET['rejected'])) {
$count = intval($_GET['rejected']);
echo '<div class="notice notice-success"><p>' . sprintf(__('%d posts rejected.', 'textdomain'), $count) . '</p></div>';
}
}
Example: User Action Notices
add_action('admin_notices', 'show_user_bulk_action_notices');
function show_user_bulk_action_notices() {
if (!empty($_GET['activated'])) {
$count = intval($_GET['activated']);
echo '<div class="notice notice-success"><p>' . sprintf(__('%d users activated.', 'textdomain'), $count) . '</p></div>';
}
if (!empty($_GET['deactivated'])) {
$count = intval($_GET['deactivated']);
echo '<div class="notice notice-success"><p>' . sprintf(__('%d users deactivated.', 'textdomain'), $count) . '</p></div>';
}
}
To add bulk actions for custom post types, replace edit-post with edit-{post_type} in the filter.
Example: For a “Books” Post Type
1add_filter('bulk_actions-edit-books', 'add_book_bulk_actions');
Add JavaScript to confirm actions before execution:
add_action('admin_footer', 'add_bulk_action_confirmation');
function add_bulk_action_confirmation() {
echo '<script>
jQuery(document).ready(function($) {
$("select[name=\'action\'], select[name=\'action2\']").on("change", function() {
if ($(this).val() === "approve") {
return confirm("Are you sure you want to approve these posts?");
}
});
});
</script>';
}
Custom bulk actions are a game-changer for managing content and users in WordPress. By following this guide, you can automate workflows, enhance functionality, and deliver a polished experience for site administrators. Always prioritize security by validating inputs and restricting access to authorized users. With these tools, you’ll unlock new levels of efficiency and customization in your WordPress projects. For detail you can visit official wordpress develper resource.

Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developer understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.