Add a WordPress Custom Bulk Action April 05 2012
Like me you probably woke up this morning assuming that adding a new bulk action to WordPress would be as easy tracking down the correct filter or implementing the right action hook. If so, then you might have had a rude awakening when you attempted to make use of the promising-looking filter named bulk-actions-screenid and failed. Thanks to a couple of posts on the subject I was able to create my own custom bulk actions, however it took enough of my time that I decided to put together a little article on the subject, and even include a full-fledged working demo plugin to hopefully make your own bulk actions that much easier to get going.
The Goal
The goal here is to describe and provide code that allows you to easily add your own custom bulk actions to any part of the WordPress admin: posts, media, users, whatever. The approach presented is based on this wordpress answers page. For this example, we’ll pretend we’re adding a custom action named “Export” to the posts page, to allow the bulk exporting of selected posts. Note that if you want to add custom bulk actions to one of the other sections, say the Users page, you’ll have to modify my code in a couple of places which I identify in the demo plugin comments. Our final result should look like this:

The Issue
That promising-looking filter bulk-actions-screenid currently only has the ability to remove bulk actions, not add them. This is clearly noted on the filters codex page, and in a code comment in the file wp-admin/includes/class-wp-list-table.php. As described in this trac ticket the issue isn’t so much how to add a new bulk action to the dropdown menu, as it is how to generically handle custom bulk actions. Since this is yet to be solved in the core, it requires a bit of hacking; however don’t worry no core files were harmed in the making of this plugin.
The Solution
Enough of the problems, on to the solution. Creating a custom bulk action breaks down to three components. First, adding an item to the bulk action select box:
add_action('admin_footer-edit.php', 'custom_bulk_admin_footer');
function custom_bulk_admin_footer() {
global $post_type;
if($post_type == 'post') {
?>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action']");
jQuery('<option>').val('export').text('<?php _e('Export')?>').appendTo("select[name='action2']");
});
</script>
<?php
}
}
As you can see, here we use javascript to inject our new bulk action item into the two bulk action select dropdowns on the Posts edit page. This piece of code certainly isn’t poetry, but until a filter capable of adding items is added to the core, it will have to do.
The next step is the code that performs the bulk action. This is done with a hook on the load-* actions, as recommended in the Q&A page referenced above. Even with demo code, this function is fairly lengthy so I’ll leave most of it out, please reference my demo plugin for the full working implementation. Its main tasks are to:
- determine the action
- perform security checks
- perform the action
- redirect the client to a results page
add_action('load-edit.php', 'custom_bulk_action');
function custom_bulk_action() {
// ...
// 1. get the action
$wp_list_table = _get_list_table('WP_Posts_List_Table');
$action = $wp_list_table->current_action();
// ...
// 2. security check
check_admin_referer('bulk-posts');
// ...
switch($action) {
// 3. Perform the action
case 'export':
// if we set up user permissions/capabilities, the code might look like:
//if ( !current_user_can($post_type_object->cap->export_post, $post_id) )
// pp_die( __('You are not allowed to export this post.') );
$exported = 0;
foreach( $post_ids as $post_id ) {
if ( !$this->perform_export($post_id) )
wp_die( __('Error exporting post.') );
$exported++;
}
// build the redirect url
$sendback = add_query_arg( array('exported' => $exported, 'ids' => join(',', $post_ids) ), $sendback );
break;
default: return;
}
// ...
// 4. Redirect client
wp_redirect($sendback);
exit();
}
The third step is to display a notice describing the result of the action by hooking into admin_notices and rendering a message if we have the ‘exported’ request parameter that was set in the previous block of code:
add_action('admin_notices', 'custom_bulk_admin_notices');
function custom_bulk_admin_notices() {
global $post_type, $pagenow;
if($pagenow == 'edit.php' && $post_type == 'post' &&
isset($_REQUEST['exported']) && (int) $_REQUEST['exported']) {
$message = sprintf( _n( 'Post exported.', '%s posts exported.', $_REQUEST['exported'] ), number_format_i18n( $_REQUEST['exported'] ) );
echo "<div class="updated"><p>{$message}</p></div>";
}
}
Which in action looks like:

Demo Plugin
And there you have it. Feel free to download and use as a starting point my demo plugin which has code similar to the above, but fully implemented and commented. Install like any other plugin, by uploading through the Admin, or by unzipping the plugin folder and placing in wp-content/plugins/. Activate the plugin, then go to Posts > All Posts and try out the ‘Export’ bulk action.
Download FoxRunSoftware Custom Bulk Action Demo Plugin
If you have any issues, or suggestions to improve the code, please leave a comment below.
The post Add a WordPress Custom Bulk Action appeared first on SkyVerge.