I would like to add a custom bulk action to a custom post type. I came across the filter bulk_actions-screenid
, which according to its documentation, would do exactly as I wish. However, after about two hours of debugging I found the following comment // This filter can currently only be used to remove actions.
on line 278 of class-wp-list-table.php – great!
I figured I could hack it by using jQuery to inject the action as an option
/**
* Hack to add a custom bulk action.
*/
public function admin_footer() {
if($_GET['post_type'] != self::POST_TYPE) return;
?>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('<option>').val('create_invoice').text('Bill').appendTo("select[name='action']");
});
</script>
<?php
}
This works. The action now appears in the bulk actions menu. I was under the assumption I could then add some logic into admin_init
to do the necessary processing – however, it appears that create_invoice
is never posted. Is there something I’m doing wrong?
=== UPDATE ===
I updated the code to use the load-*
hook. When I apply the bulk action on users.php – I see create_invoice
is passed through the request. However, on edit.php create_invoice
is never printed.
function a39x2_admin_footer() {
?>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('<option>').val('create_invoice').text('Bill').appendTo("select[name='action']");
jQuery('<option>').val('create_invoice').text('Bill').appendTo("select[name='action2']");
});
</script>
<?php
}
add_action('admin_footer', 'a39x2_admin_footer');
function a39x2_load() {
echo "<pre>" . print_r($_REQUEST, true) . "</pre>";
}
add_action('load-edit.php', 'a39x2_load');
add_action('load-users.php', 'a39x2_load');
I think the latest major release warrants a new answer to this question, considering the popularity of this question.
Since WordPress 4.7 (released December 2016) it is possible to add custom bulk actions without using JavaScript.
The filter
bulk_actions-{$screen}
(e.g.bulk_actions-edit-page
for the pages overview) now allows you to add custom bulk actions. Furthermore, a new action calledhandle_bulk_actions-{$screen}
(e.g.handle_bulk_actions-edit-page
) allows you to handle execution of the action.This is all explained pretty well in this blog post.
For example, let’s say we want to add a bulk action to email the titles of the selected items on the pages overview. We could do it like this:
For a small example, where we add an action to the bulk actions dropdown and add a handler function to it.
Adding the bulk action to the dropdown:
Adding a handler for the bulk action:
The
bulk_actions-*
filter doesn’t allow you to add custom bulk actions precisely because it’s tricky to then add a handler for a that action. Updated the Codex.I would suggest using the
load-*
action instead ofadmin_init
. Note that you have to do all the security checks like check_ajax_referrer() and current_user_can().You must use
bulk_actions
filters whenWP_Screen
object is defined.like this: