- Add your custom columns
- Populate your custom columns
- Add to the “Bulk Edit” and/or “Quick Edit” Row
- Populate Your “Quick Edit” Data
- Save Your “Quick Edit” Data
- Save Your “Bulk Edit” Data
- Download the Code
While “Quick Edit” and “Bulk Edit” are not widely used, and are kind of hidden, features, they are no less powerful and time-saving. So when a user requested they be added to CPT-onomies, I got busy learning all I could.
At first glance, it may seem like a lot of work but I’m just trying to cover all the details. If “Quick Edit” and “Bulk Edit” is what you’re after, then you’ll be glad you stuck around ’til the end.
If you’re familiar with my CPT-onomies plugin, you know that I use a Movies database in all of my examples. So for this tutorial, I will be adding a field for “Release Date”, which is post meta for my custom post type “Movies”, under “Bulk Edit” and “Quick Edit”.
1) Add your custom columns
Since the “Bulk Edit” and “Quick Edit” hooks are triggered by custom columns, you must first add custom columns for the fields you wish to add, which are setup by ‘filtering’ the column information.
There are 3 different column filters: ‘manage_pages_columns’ for pages, ‘manage_posts_columns’ which covers ALL post types (including custom post types), and ‘manage_{$post_type_name}_posts_columns’ which only covers, you guessed it, the columns for the defined $post_type_name.
The ‘manage_pages_columns’ and ‘manage_{$post_type_name}_posts_columns’ filters only pass $columns (an array), which is the column info, as an argument, but ‘manage_posts_columns’ passes $columns and $post_type (a string).
Note: Don’t forget that it’s a WordPress filter so you HAVE to return the first argument that’s passed to the function, in this case $columns. And for filters that pass more than 1 argument, you have to specify the number of accepted arguments in your add_filter() declaration, following the priority argument.
The first example adds our new column at the end. Notice that we’re specifying a post type because our function covers ALL post types:
add_filter( 'manage_posts_columns', 'rachel_carden_managing_my_posts_columns', 10, 2 );
function rachel_carden_managing_my_posts_columns( $columns, $post_type ) {
if ( $post_type == 'movies' )
$columns[ 'release_date' ] = 'Release Date';
return $columns;
}
The second example adds our new column after the “Title” column:
add_filter( 'manage_posts_columns', 'rachel_carden_managing_my_posts_columns', 10, 2 );
function rachel_carden_managing_my_posts_columns( $columns, $post_type ) {
switch ( $post_type ) {
case 'movies':
$new_columns = array();
foreach( $columns as $key => $value ) {
$new_columns[ $key ] = $value;
if ( $key == 'title' )
$new_columns[ 'release_date' ] = 'Release Date';
}
return $new_columns;
}
return $columns;
}
2) Populate your custom columns
Now that we have a column, we need to fill our column with data. The filters to populate your custom column are pretty similar to the ones that added your column: ‘manage_pages_custom_column’, ‘manage_posts_custom_column’, and ‘manage_{$post_type_name}_posts_custom_column‘. All three pass the same 2 arguments: $column_name (a string) and the $post_id (an integer).
Our custom column data is post meta so it will be a pretty simple case of retrieving the post meta with the meta key ‘release_date’.
Note that we are wrapping our post meta in a div with an id of “release_date-” plus the post id. This will come in handy when we are populating our “Quick Edit” row.
add_action( 'manage_posts_custom_column', 'rachel_carden_populating_my_posts_columns', 10, 2 );
function rachel_carden_populating_my_posts_columns( $column_name, $post_id ) {
switch( $column_name ) {
case 'release_date':
echo '<div id="release_date-' . $post_id . '">' . get_post_meta( $post_id, 'release_date', true ) . '</div>';
break;
}
}
3) Add to the “Bulk Edit” and/or “Quick Edit” Row
Now that you have your custom column, it’s bulk/quick edit showtime! The filters are ‘bulk_edit_custom_box’ and ‘quick_edit_custom_box’. Both filters pass the same 2 arguments: the $column_name (a string) and the $post_type (a string).
Your data’s form fields will obviously vary so customize at will. For this example, we’re using an input. Also take note of the css classes on the <fieldset> and <div>. There are a few other options like ‘inline-edit-col-left’ and ‘inline-edit-col-center’ for the fieldset and ‘inline-edit-col’ for the div.
add_action( 'bulk_edit_custom_box', 'rachel_carden_add_to_bulk_quick_edit_custom_box', 10, 2 );
add_action( 'quick_edit_custom_box', 'rachel_carden_add_to_bulk_quick_edit_custom_box', 10, 2 );
function rachel_carden_add_to_bulk_quick_edit_custom_box( $column_name, $post_type ) {
switch ( $post_type ) {
case 'movies':
switch( $column_name ) {
case 'release_date':
?><fieldset class="inline-edit-col-right">
<div class="inline-edit-group">
<label>
<span class="title">Release Date</span>
<input type="text" name="release_date" value="" />
</label>
</div>
</fieldset><?php
break;
}
break;
}
}
4) Populate Your “Quick Edit” Data
When you click “Quick Edit”, you may have noticed that your form fields are not populated. WordPress adds one “Quick Edit” row which moves around for each post so the information cannot be pre-populated. It has to be populated with JavaScript on a per-post “click Quick Edit” basis.
WordPress has an inline edit post function that populates all of their default quick edit fields so we want to hook into this function, in a sense, to make sure our JavaScript code is run when needed. We will “copy” the WP function, “overwrite” the WP function so we’re hooked in, “call” the original WP function (via our copy) so WordPress is not left hanging, and then run our code.
Remember where we wrapped our column data in a <div> in Step 2? This is where it comes in handy, allowing our Javascript to retrieve the data by the <div>’s element ID to populate our form field. There are other methods to retrieve your data that involve AJAX but this route is the simplest.
Don’t forget to enqueue your script and make sure it’s dependent on WordPress’s ‘inline-edit-post’ file. Since we’ll be using the jQuery library, we need to make sure ‘jquery’ is loaded as well:
add_action( 'admin_print_scripts-edit.php', 'rachel_carden_enqueue_edit_scripts' );
function rachel_carden_enqueue_edit_scripts() {
wp_enqueue_script( 'rachel-carden-admin-edit', get_bloginfo( 'stylesheet_directory' ) . '/quick_edit.js', array( 'jquery', 'inline-edit-post' ), '', true );
}
Now let’s create our JavaScript file:
(function($) {
// we create a copy of the WP inline edit post function
var $wp_inline_edit = inlineEditPost.edit;
// and then we overwrite the function with our own code
inlineEditPost.edit = function( id ) {
// "call" the original WP edit function
// we don't want to leave WordPress hanging
$wp_inline_edit.apply( this, arguments );
// now we take care of our business
// get the post ID
var $post_id = 0;
if ( typeof( id ) == 'object' )
$post_id = parseInt( this.getId( id ) );
if ( $post_id > 0 ) {
// define the edit row
var $edit_row = $( '#edit-' + $post_id );
// get the release date
var $release_date = $( '#release_date-' + $post_id ).text();
// populate the release date
$edit_row.find( 'input[name="release_date"]' ).val( $release_date );
}
};
})(jQuery);
5) Save Your “Quick Edit” Data
Saving your “Quick Edit” data is exactly like saving custom data when editing a post, using the ‘save_post’ hook. With that said, you may have already set this up. If you’re not sure, and your “Quick Edit” data is not saving, odds are you need to hook into the ‘save_post’ action.
The ‘save_post’ action passes 2 arguments: the $post_id (an integer) and the $post information (an object).
add_action( 'save_post','rachel_carden_save_post', 10, 2 );
function rachel_carden_save_post( $post_id, $post ) {
// don't save for autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
// dont save for revisions
if ( isset( $post->post_type ) && $post->post_type == 'revision' )
return $post_id;
switch( $post->post_type ) {
case 'movies':
// release date
// Because this action is run in several places, checking for the array key keeps WordPress from editing
// data that wasn't in the form, i.e. if you had this post meta on your "Quick Edit" but didn't have it
// on the "Edit Post" screen.
if ( array_key_exists( 'release_date', $_POST ) )
update_post_meta( $post_id, 'release_date', $_POST[ 'release_date' ] );
break;
}
}
6) Save Your “Bulk Edit” Data
Saving the “Bulk Edit” data is a little trickier because we have to get JavaScript involved. WordPress saves their bulk edit data via AJAX so, guess what, so do we.
Add the following code to your JavaScript file:
$( '#bulk_edit' ).live( 'click', function() {
// define the bulk edit row
var $bulk_row = $( '#bulk-edit' );
// get the selected post ids that are being edited
var $post_ids = new Array();
$bulk_row.find( '#bulk-titles' ).children().each( function() {
$post_ids.push( $( this ).attr( 'id' ).replace( /^(ttle)/i, '' ) );
});
// get the release date
var $release_date = $bulk_row.find( 'input[name="release_date"]' ).val();
// save the data
$.ajax({
url: ajaxurl, // this is a variable that WordPress has already defined for us
type: 'POST',
async: false,
cache: false,
data: {
action: 'rachel_carden_save_bulk_edit', // this is the name of our WP AJAX function that we'll set up next
post_ids: $post_ids, // and these are the 2 parameters we're passing to our function
release_date: $release_date
}
});
});
Now we need to setup the WordPress AJAX function that will handle and save our data:
add_action( 'wp_ajax_rachel_carden_save_bulk_edit', 'rachel_carden_save_bulk_edit' );
function rachel_carden_save_bulk_edit() {
// get our variables
$post_ids = ( isset( $_POST[ 'post_ids' ] ) && !empty( $_POST[ 'post_ids' ] ) ) ? $_POST[ 'post_ids' ] : array();
$release_date = ( isset( $_POST[ 'release_date' ] ) && !empty( $_POST[ 'release_date' ] ) ) ? $_POST[ 'release_date' ] : NULL;
// if everything is in order
if ( !empty( $post_ids ) && is_array( $post_ids ) && !empty( $release_date ) ) {
foreach( $post_ids as $post_id ) {
update_post_meta( $post_id, 'release_date', $release_date );
}
}
}
7) Download the Code
See? That wasn’t too bad. I’ll even give you the code all nice and neat. Go nuts, buddy.

Pingback: Earthman Web & Media on "Expiration date added to Quick Edit screen?" | Upgrade Wordpress