Using Custom Bulk Actions

Sorry it’s been such a long time since my last blogblog (versus network, site)!

I’m happy to tell you that in WordPress 4.7, developers can register their own bulk actions on list table screens.


Let’s walk through the steps required to add one.

An option in the dropdown

To add an option in the Bulk Actions dropdown HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. element, register a callback on the bulk_actions-{screen_id} filterFilter Filters are one of the two types of Hooks They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. that adds the new option onto the array. Replace {screen_id} with the ID of the admin screen to offer the bulk action on.

To add a bulk action “Email to Eric,” we could use the following code:

add_filter( 'bulk_actions-edit-post', 'register_my_bulk_actions' );

function register_my_bulk_actions($bulk_actions) {
  $bulk_actions['email_to_eric'] = __( 'Email to Eric', 'email_to_eric');
  return $bulk_actions;

Handling the form submission

To handle a bulk action form submission, register a callback on the handle_bulk_actions-{screen_id} filter for the corresponding screen. The filter expects the redirect URLURL A specific web address of a website or web page on the Internet, such as a website’s URL to be modified, so be sure to modify the passed $redirect_url. This allows us to carry success or failure state into the next request to display a notice to the user. The other callback arguments will differ depending on the screen here to include contextually relevant data.

To add a bulk action handler for emailing the selected posts, we could use the following code:

add_filter( 'handle_bulk_actions-edit-post', 'my_bulk_action_handler', 10, 3 );

function my_bulk_action_handler( $redirect_to, $doaction, $post_ids ) {
  if ( $doaction !== 'email_to_eric' ) {
    return $redirect_to;
  foreach ( $post_ids as $post_id ) {
    // Perform action for each post.
  $redirect_to = add_query_arg( 'bulk_emailed_posts', count( $post_ids ), $redirect_to );
  return $redirect_to;

Showing notices

We could use the existing notice hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. to let the user know what happened, depending on the state we set in the URL:

add_action( 'admin_notices', 'my_bulk_action_admin_notice' );

function my_bulk_action_admin_notice() {
  if ( ! empty( $_REQUEST['bulk_emailed_posts'] ) ) {
    $emailed_count = intval( $_REQUEST['bulk_emailed_posts'] );
    printf( '<div id="message" class="updated fade">' .
      _n( 'Emailed %s post to Eric.',
        'Emailed %s posts to Eric.',
      ) . '</div>', $emailed_count );

For the curious, see the related changeset and Trac ticket.