我有一个叫company
使用自定义字段url
和partner
.
自定义列在CPT admin表中正确显示,内容正确。还将显示并正确填充每行的快速字段。
在“快速编辑”中单击“更新”按钮时,post\\u meta会正确更新,值保存在数据库中,但Ajax不会更新列的内容。如果刷新页面,则会正确显示页面自定义列,但此快速编辑的全部目的是避免页面刷新。客户端将不知道其更改已保存,并将保持快速编辑并丢失数据。我错过了什么?
EDIT: 我的问题是因为一个与PODS相关的缓存功能,这是一个用于自定义port\\u meta和字段的框架。快速编辑后返回了行,但缓存了值。我重写了这些函数的缓存,一切都正常工作。
Full working code with Quick & Bulk Edit
自定义列:
add_filter(
\'manage_company_posts_columns\',
function () {
return [
\'cb\' => true,
\'title\' => _x( \'Title\', \'column name\' ),
\'partner\' => \'Partner\',
\'date\' => __( \'Date\' ),
\'last_updated\' => __( \'Last Updated\' ),
];
}
);
自定义列内容
add_action(
\'manage_company_posts_custom_column\',
function ( $column, $post_id ) {
if ( \'last_updated\' == $column ) {
$post_modified = get_post_field( \'post_modified\', $post_id );
if ( ! $post_modified ) {
$post_modified = \'Undefined\';
}
echo date( \'Y-m-d\', strtotime( $post_modified ) );
}
if ( \'partner\' == $column ) {
if ( get_post_meta( $post_id , \'partner\' , true ) !== \'0\' ) {
echo \'<a href="\'.get_post_meta($post_id , \'url\' , true ) .\'">
<span class="partner">Partner Company</span></a>\';
} else {
echo \'Not a partner company.\';
}
}, 10, 2
);
快速编辑字段
add_action(
\'quick_edit_custom_box\',
function ( $column_name, $post_type ) {
if ( $post_type != \'company\' ) return;
switch( $column_name ) :
case \'partner\': {
wp_nonce_field( \'company_cpt_quick_edit\', \'my_nonce\' );
?>
<fieldset class="inline-edit-col-right">
<div class="inline-edit-col">
<div class="inline-edit-group wp-clearfix">
<label class="alignleft">
<span class="title">Company URL</span>
<input type="text" name="url" value="">
</label>
<label class="alignleft">
<input type="checkbox" name="partner">
<span class="checkbox-title">Partner Company</span>
</label>
</div>
</div>
</fieldset>
<?php
break;
}
endswitch;
}, 10, 2
);
保存Post操作
add_action(
\'save_post\',
function ( $post_id ){
if ( empty( $_POST ) ) return $post_id;
if ( !current_user_can( \'edit_post\', $post_id ) ) return $post_id;
if ( !wp_verify_nonce( $_POST[\'my_nonce\'], \'company_cpt_quick_edit\' ) ) return $post_id;
if ( defined( \'DOING_AUTOSAVE\' ) && DOING_AUTOSAVE ) return $post_id;
if ( isset( $post->post_type ) && $post->post_type == \'revision\' ) return $post_id;
if ( isset( $_POST[\'url\'] ) ) {
update_post_meta( $post_id, \'url\', $_POST[\'url\'] );
}
if ( isset( $_POST[\'partner\'] ) ) {
update_post_meta( $post_id, \'partner\', \'1\' );
} else {
update_post_meta( $post_id, \'partner\', \'0\' );
}
}
);
用于快速编辑的JavaScript
jQuery(function($){
var wp_inline_edit_function = inlineEditPost.edit;
inlineEditPost.edit = function( post_id ) {
wp_inline_edit_function.apply( this, arguments );
var id = 0;
if ( typeof( post_id ) == \'object\' ) {
id = parseInt( this.getId( post_id ) );
}
if ( id > 0 ) {
var specific_post_edit_row = $( \'#edit-\' + id ),
specific_post_row = $( \'#post-\' + id ),
url = $( \'.column-partner\', specific_post_row ).find(\'a:first\').attr(\'href\'),
partner = false;
if( $( \'.column-partner\', specific_post_row ).find(\'span.partner\').length !== 0 ) partner = true;
$( \':input[name="url"]\', specific_post_edit_row ).val( url );
$( \':input[name="partner"]\', specific_post_edit_row ).prop(\'checked\', partner );
}
}
});
批量编辑单选字段
add_action(
\'bulk_edit_custom_box\',
function ( $column_name, $post_type ) {
if ( $post_type != \'company_single\' ) return;
switch( $column_name ) :
case \'partner\': {
?>
<fieldset class="inline-edit-col-right">
<div class="inline-edit-col">
<div class="inline-edit-group wp-clearfix">
<label class="alignleft">
<input type="radio" id="partner" name="partner" class="partner" value="0">
<label for="partner">Partner</label>
<input type="radio" id="non_partner" name="partner" class="partner" value="1">
<label for="non_partner" >Non-partner</label>
</label>
</div>
</div>
</fieldset>
<?php
break;
}
endswitch;
}, 10, 2
);
批量编辑保存功能
function company_bulk_edit_save_hook() {
if( empty( $_POST[ \'post_ids\' ] ) ) {
die();
}
foreach( $_POST[ \'post_ids\' ] as $id ) {
if ( isset( $_POST[\'partner\'] ) ) {
update_post_meta( $id, \'partner\', $_POST[\'partner\'] );
} else {
update_post_meta( $id, \'partner\', \'0\' );
}
}
wp_die();
}
add_action( \'wp_ajax_company_bulk_edit_save\', \'company_bulk_edit_save_hook\' );
用于批量编辑的AJAX
jQuery(function($){
$( \'body\' ).on( \'click\', \'input[name="bulk_edit"]\', function() {
$( this ).after(\'<span class="spinner is-active"></span>\');
var bulk_edit_row = $( \'tr#bulk-edit\' ),
post_ids = new Array(),
partner = bulk_edit_row.find( \'.partner:checked\' ).val();
bulk_edit_row.find( \'#bulk-titles\' ).children().each( function() {
post_ids.push( $( this ).attr( \'id\' ).replace( /^(ttle)/i, \'\' ) );
});
$.ajax({
url: ajaxurl,
type: \'POST\',
async: false,
cache: false,
data: {
action: \'company_bulk_edit_save\',
post_ids: post_ids,
partner: partner
}
});
});
});
最合适的回答,由SO网友:Tom J Nowell 整理而成
在“快速编辑”中单击“更新”按钮时,post\\u meta会正确更新,值保存在数据库中,但Ajax不会更新列的内容。
实际上,快速编辑功能不会试图更新或重新加载单个管理列。相反,它用AJAX端点返回的任何内容替换该行。
以下是实施:
https://github.com/WordPress/WordPress/blob/master/wp-admin/js/inline-edit-post.js#L386-L451
/**
* Saves the changes made in the quick edit window to the post.
* Ajax saving is only for Quick Edit and not for bulk edit.
*
* @since 2.7.0
*
* @param {number} id The ID for the post that has been changed.
* @return {boolean} False, so the form does not submit when pressing
* Enter on a focused field.
*/
save : function(id) {
var params, fields, page = $(\'.post_status_page\').val() || \'\';
if ( typeof(id) === \'object\' ) {
id = this.getId(id);
}
$( \'table.widefat .spinner\' ).addClass( \'is-active\' );
params = {
action: \'inline-save\',
post_type: typenow,
post_ID: id,
edit_date: \'true\',
post_status: page
};
fields = $(\'#edit-\'+id).find(\':input\').serialize();
params = fields + \'&\' + $.param(params);
// Make Ajax request.
$.post( ajaxurl, params,
function(r) {
var $errorNotice = $( \'#edit-\' + id + \' .inline-edit-save .notice-error\' ),
$error = $errorNotice.find( \'.error\' );
$( \'table.widefat .spinner\' ).removeClass( \'is-active\' );
if (r) {
if ( -1 !== r.indexOf( \'<tr\' ) ) {
$(inlineEditPost.what+id).siblings(\'tr.hidden\').addBack().remove();
$(\'#edit-\'+id).before(r).remove();
$( inlineEditPost.what + id ).hide().fadeIn( 400, function() {
// Move focus back to the Quick Edit button. $( this ) is the row being animated.
$( this ).find( \'.editinline\' )
.attr( \'aria-expanded\', \'false\' )
.focus();
wp.a11y.speak( wp.i18n.__( \'Changes saved.\' ) );
});
} else {
r = r.replace( /<.[^<>]*?>/g, \'\' );
$errorNotice.removeClass( \'hidden\' );
$error.html( r );
wp.a11y.speak( $error.text() );
}
} else {
$errorNotice.removeClass( \'hidden\' );
$error.text( wp.i18n.__( \'Error while saving the changes.\' ) );
wp.a11y.speak( wp.i18n.__( \'Error while saving the changes.\' ) );
}
},
\'html\');
// Prevent submitting the form when pressing Enter on a focused field.
return false;
},
处理此问题的函数是
function wp_ajax_inline_save() {
https://github.com/WordPress/WordPress/blob/0e3147c40e91f6eb1f57585724be173e3c04a719/wp-admin/includes/ajax-actions.php#L1981
这与在classic editor中支持post更新的功能相同。
因此,我使用以下代码测试了一个自定义列:
<?php
/**
* Plugin Name: Custom columns
*/
add_filter(
\'manage_post_posts_columns\',
function( $columns ) {
return array_merge( $columns, [ \'tomcol\' => \'Toms Awesome Column\' ] );
}
);
add_action(
\'manage_post_posts_custom_column\',
function ( $column_key, $post_id ) {
if ( $column_key === \'tomcol\' ) {
$meta = get_post_meta( $post_id, \'tomcol\', true );
echo esc_html( $meta );
}
},
10,
2
);
add_action(
\'quick_edit_custom_box\',
function ( $column_name, $post_type ) {
if ( \'tomcol\' !== $column_name ) {
return;
}
$meta = get_post_meta( $post_id, \'tomcol\', true );
?>
<fieldset class="inline-edit-col-right">
<div class="inline-edit-col">
<div class="inline-edit-group wp-clearfix">
<label class="alignleft">
<span class="title">Toms Column</span>
<input type="text" name="tomcol" value="<?php echo esc_html( $meta ); ?>">
</label>
</div>
</div>
</fieldset>
<?php
},
10,
2
);
add_action(
\'admin_footer\',
function () {
?>
<script>
jQuery( function( $ ) {
var wp_inline_edit_function = inlineEditPost.edit;
inlineEditPost.edit = function( post_id ) {
wp_inline_edit_function.apply( this, arguments );
var id = 0;
if ( typeof( post_id ) == \'object\' ) {
id = parseInt( this.getId( post_id ) );
}
if ( id > 0 ) {
var specific_post_edit_row = $( \'#edit-\' + id );
var specific_post_row = $( \'#post-\' + id );
var url = $( \'.column-tomcol\', specific_post_row ).text();
$( \':input[name="tomcol"]\', specific_post_edit_row ).val( url );
}
}
});
</script>
<?php
}
);
add_action(
\'save_post\',
function ( $post_id ){
global $post;
if ( empty( $_POST ) ) {
return $post_id;
}
if ( ! current_user_can( \'edit_post\', $post_id ) ) {
return $post_id;
}
if ( defined( \'DOING_AUTOSAVE\' ) && DOING_AUTOSAVE ) {
return $post_id;
}
if ( isset( $post->post_type ) && $post->post_type == \'revision\' ) {
return $post_id;
}
if ( isset( $_POST[\'tomcol\'] ) ) {
update_post_meta( $post_id, \'tomcol\', sanitize_text_field( wp_unslash( $_POST[\'tomcol\'] ) ) );
}
}
);
它成功了。该列在AJAX刷新时更新。因此,我只能得出结论,你的专栏确实在更新,但价值观陈旧,或者在某个地方犯了愚蠢的错误/打字错误
然而,重要的区别是,列没有更新,而是行被完全替换