How can I add a new column to quick edit and put a custom field in it? I read this question but one of the links lead to an error 404. I need a new column for my custom meta key, “summary
” and post types, “post
” and “episode
“.
2 Answers
There are a few steps to create the custom quick edit box and custom column
- create a custom meta key (assumed that you have 1 already)
- add custom admin column title and data (assumed that you want to shows the custom meta key in the column, if not, you may also modify a bit of the logic to accomplish the same effect because the principal is the same)
- add custom quick edit box
- add save logic
- load script to modify original inline-edit-post function in order to support custom meta value
- prepare the script file
This example is going to add a quick edit input box in post type Page
. The following code is proved to work by putting in functions.php .
1. create a custom meta key (assumed that you have 1 already)
I have prepared a custom meta key remark
for post type page
2. add custom admin column title and data
for custom post type, you may use
Add column title
- For specific Screen ID manage_{$screen->id}_columns
- Specificially for Page manage_pages_columns
- Specificially for generic (default Post or custom post type) manage_posts_custom_column or for specific post type manage_{$post->post_type}_posts_custom_column to add column data
Add column content
- Generic (default Post or custom post type) manage_posts_columns with custom post type checking using post type argument or for specific post type manage_{$post_type}_posts_columns to add column title
The following is an example for post type Page as well as custom post type + default Post
as an example for multiple post types setup.
// add custom column title for custom meta value
add_filter('manage_edit-page_columns', 'ws365150_add_custom_columns_title' );
function ws365150_add_custom_columns_title( $columns ) {
$columns['page_remark'] = 'Remark'; // you may use __() later on for translation support
return $columns;
}
// add custom column data with custom meta value
add_action('manage_pages_custom_column', 'ws365150_add_custom_column_data', 10, 2 );
function ws365150_add_custom_column_data( $column_name, $post_id ) {
switch ( $column_name ) {
case 'page_remark':
echo get_post_meta( $post_id, 'remark', true );
break;
default:
break;
}
}
The following is an example for custom post type episode
+ default Post
with meta key summary
// add custom column title for custom meta value
// 'manage_pages_columns' or 'manage_edit-post_columns' both works
add_filter('manage_posts_columns', 'ws365150_add_custom_columns_title_pt', 10, 2 );
function ws365150_add_custom_columns_title_pt( $columns, $post_type ) {
switch ( $post_type ) {
case 'post':
case 'episode':
$columns['ws365150_summary'] = 'Summary'; // you may use __() later on for translation support
break;
default:
break;
}
return $columns;
}
// add custom column data with custom meta value for custom post types
add_action('manage_posts_custom_column', 'ws365150_add_custom_column_data_pt', 10, 2 );
function ws365150_add_custom_column_data_pt( $column_name, $post_id ) {
switch ( $column_name ) {
case 'ws365150_summary': // specified for this column assigned in the column title
echo get_post_meta( $post_id, 'summary', true );
break;
default:
break;
}
}
3. add custom quick edit box
// for page
add_action( 'quick_edit_custom_box', 'ws365150_custom_edit_box', 10, 3 );
function ws365150_custom_edit_box( $column_name, $post_type, $taxonomy ) {
global $post;
switch ( $post_type ) {
case 'page':
if( $column_name === 'page_remark' ): // same column title as defined in previous step
?>
<?php // echo get_post_meta( $post->ID, 'remark', true ); ?>
<fieldset class="inline-edit-col-right" id="#edit-">
<div class="inline-edit-col">
<label>
<span class="title">Remark</span>
<span class="input-text-wrap"><input type="text" name="remark" class="inline-edit-menu-order-input" value=""></span>
</label>
</div>
</fieldset>
<?php
endif;
// echo 'custom page field';
break;
default:
break;
}
}
// for Post + custom post type
add_action( 'quick_edit_custom_box', 'ws365150_custom_edit_box_pt', 10, 3 );
function ws365150_custom_edit_box_pt( $column_name, $post_type, $taxonomy ) {
global $post;
switch ( $post_type ) {
case 'post':
case 'episode':
if( $column_name === 'ws365150_summary' ): // same column title as defined in previous step
?>
<?php // echo get_post_meta( $post->ID, 'remark', true ); ?>
<fieldset class="inline-edit-col-right" id="#edit-">
<div class="inline-edit-col">
<label>
<span class="title">Summary</span>
<span class="input-text-wrap"><input type="text" name="summary" class="inline-edit-menu-order-input" value=""></span>
</label>
</div>
</fieldset>
<?php
endif;
// echo 'custom page field';
break;
default:
break;
}
}
4. add save logic
add_action( 'save_post', 'ws365150_update_custom_quickedit_box' );
function ws365150_update_custom_quickedit_box() {
// any checking logic here, skip and keep it simple for simple illustration purpose (nonce, existing of $_POST['remark'], ajax save and so on
// remark in Page
if( isset( $_POST ) && isset( $_POST['remark'] ) ) { // where remark is defined in the <input name="remark">
update_post_meta($_POST['post_ID'], 'remark', $_POST['remark']);
}
// summary in Post, custom post type
if( isset( $_POST ) && isset( $_POST['summary'] ) ) { // where summary is defined in the <input name="summary">
update_post_meta($_POST['post_ID'], 'summary', $_POST['summary']);
}
// for debugging purpose in inspector, not necessary, enable this will break the saving but could see the ajax return
// wp_send_json_success( array(
// 'message' => 'Save test!',
// 'post_data' => $_POST,
// ) );
return; // finish the function call
}
5. load script to modify original inline-edit-post function
add_action( 'admin_enqueue_scripts', function( $page ) {
// add page checking logic, this is a simple one, you may test post type and so on...
if ( 'edit.php' != $page ) {
return;
}
wp_enqueue_script( 'custom-quickedit-box', get_stylesheet_directory_uri() . '/ws365150_custom_quickedit_box.js', array( 'jquery', 'inline-edit-post' ) );
});
6. prepare the script file (ws365150_custom_quickedit_box.js, when test the above code, put in the theme folder)
( function( $, wp ) {
// clone from original function in inline-post-edit.js for override
// actually no need to create an alias object, however, create an alias could be a note and mark of override without forgetting for later maintenance
window.customInlineEditPost = window.inlineEditPost;
// function override: add custom meta value, the base is copied from the source
customInlineEditPost.edit = function(id) {
// console.log( 'custom edit' );
var t = this, fields, editRow, rowData, status, pageOpt, pageLevel, nextPage, pageLoop = true, nextLevel, f, val, pw;
t.revert();
if ( typeof(id) === 'object' ) {
id = t.getId(id);
}
fields = ['post_title', 'post_name', 'post_author', '_status', 'jj', 'mm', 'aa', 'hh', 'mn', 'ss', 'post_password', 'post_format', 'menu_order', 'page_template'];
if ( t.type === 'page' ) {
fields.push('post_parent');
}
// Add the new edit row with an extra blank row underneath to maintain zebra striping.
editRow = $('#inline-edit').clone(true);
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
$(t.what+id).removeClass('is-expanded').hide().after(editRow).after('<tr class="hidden"></tr>');
// Populate fields in the quick edit window.
rowData = $('#inline_'+id);
if ( !$(':input[name="post_author"] option[value="' + $('.post_author', rowData).text() + '"]', editRow).val() ) {
// The post author no longer has edit capabilities, so we need to add them to the list of authors.
$(':input[name="post_author"]', editRow).prepend('<option value="' + $('.post_author', rowData).text() + '">' + $('#' + t.type + '-' + id + ' .author').text() + '</option>');
}
if ( $( ':input[name="post_author"] option', editRow ).length === 1 ) {
$('label.inline-edit-author', editRow).hide();
}
// populate custom meta value
if ( $( ':input[name="remark"]', editRow ).length === 1 ) {
$( ':input[name="remark"]', editRow ).val( $('#post-' + id + ' .page_remark').text() );
}
if ( $( ':input[name="summary"]', editRow ).length === 1 ) {
$( ':input[name="summary"]', editRow ).val( $('#post-' + id + ' .ws365150_summary').text() );
}
for ( f = 0; f < fields.length; f++ ) {
val = $('.'+fields[f], rowData);
/**
* Replaces the image for a Twemoji(Twitter emoji) with it's alternate text.
*
* @returns Alternate text from the image.
*/
val.find( 'img' ).replaceWith( function() { return this.alt; } );
val = val.text();
$(':input[name="' + fields[f] + '"]', editRow).val( val );
}
if ( $( '.comment_status', rowData ).text() === 'open' ) {
$( 'input[name="comment_status"]', editRow ).prop( 'checked', true );
}
if ( $( '.ping_status', rowData ).text() === 'open' ) {
$( 'input[name="ping_status"]', editRow ).prop( 'checked', true );
}
if ( $( '.sticky', rowData ).text() === 'sticky' ) {
$( 'input[name="sticky"]', editRow ).prop( 'checked', true );
}
/**
* Creates the select boxes for the categories.
*/
$('.post_category', rowData).each(function(){
var taxname,
term_ids = $(this).text();
if ( term_ids ) {
taxname = $(this).attr('id').replace('_'+id, '');
$('ul.'+taxname+'-checklist :checkbox', editRow).val(term_ids.split(','));
}
});
/**
* Gets all the taxonomies for live auto-fill suggestions when typing the name
* of a tag.
*/
$('.tags_input', rowData).each(function(){
var terms = $(this),
taxname = $(this).attr('id').replace('_' + id, ''),
textarea = $('textarea.tax_input_' + taxname, editRow),
comma = inlineEditL10n.comma;
terms.find( 'img' ).replaceWith( function() { return this.alt; } );
terms = terms.text();
if ( terms ) {
if ( ',' !== comma ) {
terms = terms.replace(/,/g, comma);
}
textarea.val(terms);
}
textarea.wpTagsSuggest();
});
// Handle the post status.
status = $('._status', rowData).text();
if ( 'future' !== status ) {
$('select[name="_status"] option[value="future"]', editRow).remove();
}
pw = $( '.inline-edit-password-input' ).prop( 'disabled', false );
if ( 'private' === status ) {
$('input[name="keep_private"]', editRow).prop('checked', true);
pw.val( '' ).prop( 'disabled', true );
}
// Remove the current page and children from the parent dropdown.
pageOpt = $('select[name="post_parent"] option[value="' + id + '"]', editRow);
if ( pageOpt.length > 0 ) {
pageLevel = pageOpt[0].className.split('-')[1];
nextPage = pageOpt;
while ( pageLoop ) {
nextPage = nextPage.next('option');
if ( nextPage.length === 0 ) {
break;
}
nextLevel = nextPage[0].className.split('-')[1];
if ( nextLevel <= pageLevel ) {
pageLoop = false;
} else {
nextPage.remove();
nextPage = pageOpt;
}
}
pageOpt.remove();
}
$(editRow).attr('id', 'edit-'+id).addClass('inline-editor').show();
$('.ptitle', editRow).focus();
return false;
};
})( jQuery, window.wp );
The above is for quick edit using quick_edit_custom_box
hook, and you may need to take care of bulk edit also. You may explore more by reading and using bulk_edit_custom_box
.