快速编辑保存后,CPT管理表中的自定义列未更新

时间:2020-11-07 作者:GeorgeP

我有一个叫company 使用自定义字段urlpartner.

自定义列在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
            }
        });
    });
});

1 个回复
最合适的回答,由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刷新时更新。因此,我只能得出结论,你的专栏确实在更新,但价值观陈旧,或者在某个地方犯了愚蠢的错误/打字错误

然而,重要的区别是,列没有更新,而是行被完全替换

相关推荐

如何让`wp-list-table`显示我在Custom-Post中的`Custom-Fields`

一切都好吗<我需要wp-list-table 也要显示custom-fields 在每个custom-post 我有,但我不知道如何做到这一点,在这幅图中,它显示了带有字段的表格:Title, Author and Publication Date: 我想要的是能够选择custom-fields 将出现,例如以下示例Title, Carta, Naipe, Author, and Date of Publication: