quick_edit_custom_box
is an action that lets a plugin print inputs for custom columns when quick editing. This action is called one time for each custom column. Custom columns are added with the manage_edit-${post_type}_columns filter. To save the data from the custom inputs, hook the save_post action.
A registered action function is passed the following parameters.
Note that the action function is passed neither the post ID nor any existing value for the column.
add_action( 'quick_edit_custom_box', 'display_custom_quickedit_book', 10, 2 );
function display_custom_quickedit_book( $column_name, $post_type ) {
static $printNonce = TRUE;
if ( $printNonce ) {
$printNonce = FALSE;
wp_nonce_field( plugin_basename( __FILE__ ), 'book_edit_nonce' );
}
?>
<fieldset class="inline-edit-col-right inline-edit-book">
<div class="inline-edit-col column-<?php echo $column_name; ?>">
<label class="inline-edit-group">
<?php
switch ( $column_name ) {
case 'book_author':
?><span class="title">Author</span><input name="book_author" /><?php
break;
case 'inprint':
?><span class="title">In Print</span><input name="inprint" type="checkbox" /><?php
break;
}
?>
</label>
</div>
</fieldset>
<?php
}
Data entered in custom inputs can be saved by hooking the save_post action.
add_action( 'save_post', 'save_book_meta' );
function save_book_meta( $post_id ) {
/* in production code, $slug should be set only once in the plugin,
preferably as a class property, rather than in each function that needs it.
*/
$slug = 'book';
if ( $slug !== $_POST['post_type'] ) {
return;
}
if ( !current_user_can( 'edit_post', $post_id ) ) {
return;
}
$_POST += array("{$slug}_edit_nonce" => '');
if ( !wp_verify_nonce( $_POST["{$slug}_edit_nonce"],
plugin_basename( __FILE__ ) ) )
{
return;
}
if ( isset( $_REQUEST['book_author'] ) ) {
update_post_meta( $post_id, 'author', $_REQUEST['book_author'] );
}
# checkboxes are submitted if checked, absent if not
if ( isset( $_REQUEST['inprint'] ) ) {
update_post_meta($post_id, 'inprint', TRUE);
} else {
update_post_meta($post_id, 'inprint', FALSE);
}
}
Populating inputs with existing values takes a bit of trickery. One can't simply access the $post
global because when this action is run, $post
refers only to the last post (the quick edit inputs are created only once, and cloned as needed when quick editing a column). There are two parts: storing the data on the page and hooking inlineEditPost.edit
to set the input values. If the quick-edit columns are also displayed as custom columns, the data is already in the table. Otherwise, it can be added as hidden elements to an existing custom column.
Hooking inlineEditPost.edit
must be done in a JS script, loaded after wp-admin/js/inline-edit-post.js
. The original method is saved and replaced with a new one which calls the original. This particular technique is a simple example of aspect-oriented programming.
/* load script in the footer */
if ( ! function_exists('wp_my_admin_enqueue_scripts') ):
function wp_my_admin_enqueue_scripts( $hook ) {
if ( 'edit.php' === $hook &&
isset( $_GET['post_type'] ) &&
'book' === $_GET['post_type'] ) {
wp_enqueue_script( 'my_custom_script', plugins_url('scripts/admin_edit.js', __FILE__),
false, null, true );
}
}
endif;
add_action( 'admin_enqueue_scripts', 'wp_my_admin_enqueue_scripts' );
/* example of how an existing value can be stored in the table */
add_action( 'manage_book_posts_custom_column' , 'custom_book_column', 10, 2 );
function custom_book_column( $column, $post_id ) {
switch ( $column ) {
case 'inprint':
// the !! means translate the following item to a boolean value
if ( !!get_post_meta( $post_id , 'inprint' , true ) ) {
$checked = 'checked';
} else {
$checked = '';
}
echo "<input type='checkbox' readonly $checked/>";
break;
case 'book_author':
# ...
}
}
scripts/admin_edit.js
:
(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 );
var $post_row = $( '#post-' + $post_id );
// get the data
var $book_author = $( '.column-book_author', $post_row ).text();
var $inprint = !! $('.column-inprint>*', $post_row ).prop('checked');
// populate the data
$( ':input[name="book_author"]', $edit_row ).val( $book_author );
$( ':input[name="inprint"]', $edit_row ).prop('checked', $inprint );
}
};
})(jQuery);
wp-admin/includes/class-wp-terms-list-table.php
in 3.1wp-admin/includes/template.php
wp-admin/includes/class-wp-posts-list-table.php
, and by WP_Terms_List_Table->inline_edit in wp-admin/includes/class-wp-terms-list-table.php
.