在 WooCommerce 产品类别设置中为特色帖子添加 multi-select 字段

Add a multi-select field for featured Posts in WooCommerce Product Category settings

我正在制作一个简单的插件,用户可以在其中为每个 woocommerce 产品类别选择自定义 post 或 post 列表。我正在使用 select2 选择 post 列表 为什么它不节省? 无法保存该字段的数据。

<?php 
if ( ! defined( 'ABSPATH' ) ) {  exit;  }

/*----------------------------------------------------------------------
Adding Ajax Search for POSTS
-------------------------------------------------------------------------*/
function ex_get_posts_ajax_callback(){
 global $post;
    // we will pass post IDs and titles to this array
    $return = array();

    // you can use WP_Query, query_posts() or get_posts() here - it doesn't matter
    $search_results = new WP_Query( array( 
        's'=> $_GET['q'], // the search query
        'post_type' => 'post',//post type
        'post_status' => 'publish', // if you don't want drafts to be returned
        'ignore_sticky_posts' => 1,
        'posts_per_page' => 20 // how much to show at once
    ) );
    if( $search_results->have_posts() ) :
        while( $search_results->have_posts() ) : $search_results->the_post();   
            // shorten the title a little
            $title = ( mb_strlen( $search_results->post->post_title ) > 50 ) ? mb_substr( $search_results->post->post_title, 0, 49 ) . '...' : $search_results->post->post_title;
            $return[] = array( $search_results->post->ID, $title ); // array( Post ID, Post Title )
        endwhile;
    endif;
    wp_send_json( $return );
}
add_action( 'wp_ajax_getpostsearch', 'ex_get_posts_ajax_callback' ); // wp_ajax_{action}




//html output for edit field
function ex_product_cat_feature_posts($post_object) {
    global $post;
    // Nonce field to validate form request came from current site
    wp_nonce_field( basename( __FILE__ ), '_feature_post_nonce' );

    $html = '';

    // always array because we have added [] to our <select> name attribute
    $ex_product_cat_feature_post = get_post_meta( $post_object->ID, 'ex_product_cat_feature_post', true );

    $html .= '<tr class="form-field">';
    $html .= '<th scope="row" valign="top"><label for="catshort_button_type">Select Feature post:</label></th>';
    $html .= '<td>';
    $html .= '<select id="ex_product_cat_feature_post" name="ex_product_cat_feature_post[]" multiple="multiple" style="width:99%;max-width:25em;">';

    if( $ex_product_cat_feature_post ) {
        foreach( $ex_product_cat_feature_post as $post_id ) {
            $title = get_the_title( $post_id );
            // if the post title is too long, truncate it and add "..." at the end
            $title = ( mb_strlen( $title ) > 50 ) ? mb_substr( $title, 0, 49 ) . '...' : $title;
            $html .=  '<option value="' . $post_id . '" selected="selected">' . $title . '</option>';
        }
    }
    $html .= '</select>';
    $html .= '</td>';
    $html .= '</tr>';

    echo $html;
    //==========================================
    ?>
    <script>
    (function ($) {
        'use strict';
    $(function () {
        //--------------------------------------------------------------------------
        // multiple select with AJAX search
        $('#ex_product_cat_feature_post').select2({
            ajax: {
                    url: ajaxurl, // AJAX URL is predefined in WordPress admin
                    dataType: 'json',
                    delay: 250, // delay in ms while typing when to perform a AJAX search
                    data: function (params) {
                        return {
                            q: params.term, // search query
                            action: 'getpostsearch' // AJAX action for admin-ajax.php
                        };
                    },
                    processResults: function( data ) {
                    var options = [];
                    if ( data ) {

                        // data is the array of arrays, and each of them contains ID and the Label of the option
                        $.each( data, function( index, text ) { // do not forget that "index" is just auto incremented value
                            options.push( { id: text[0], text: text[1]  } );
                        });

                    }
                    return {
                        results: options
                    };
                },
                cache: true
            },
            minimumInputLength: 3 // the minimum of symbols to input before perform a search
        });

        //----------------------------------------------------------------------------------------
    });
})(jQuery);
</script>   
<style type="text/css">
     iframe#description_ifr{
            min-height:220px !important;
     }
</style>
    <?php 
}

add_action('product_cat_add_form_fields', 'ex_product_cat_feature_posts', 10, 1);
add_action('product_cat_edit_form_fields', 'ex_product_cat_feature_posts', 10, 1);


// Save extra taxonomy fields callback function.
function ex_product_cat_feature_posts_save($term_id) {
    $ex_product_cat_feature_post     = filter_input(INPUT_POST, 'ex_product_cat_feature_post');

    update_term_meta($term_id, 'ex_product_cat_feature_post', $ex_product_cat_feature_post);
}

add_action('edited_product_cat', 'ex_product_cat_feature_posts_save', 10, 1);
add_action('create_product_cat', 'ex_product_cat_feature_posts_save', 10, 1);

主要问题是保存数据时(最后一个函数)。我主要重新访问了你的最后两个功能,主要是最后一个:

// Adding Ajax Search for POSTS - wp_ajax_{action}
add_action( 'wp_ajax_getpostsearch', 'ex_get_posts_ajax_callback' );
function ex_get_posts_ajax_callback(){
    $return = array(); // we will pass post IDs and titles to this array

    // You can use WP_Query, query_posts() or get_posts() here - it doesn't matter
    $search_results = new WP_Query( array(
        's'=> $_GET['q'], // the search query
        'post_type' => 'post',//post type
        'post_status' => 'publish', // if you don't want drafts to be returned
        'ignore_sticky_posts' => 1,
        'posts_per_page' => 20 // how much to show at once
    ) );
    if( $search_results->have_posts() ) :
        while( $search_results->have_posts() ) : $search_results->the_post();
            // shorten the title a little
            $title = ( mb_strlen( $search_results->post->post_title ) > 50 ) ? mb_substr( $search_results->post->post_title, 0, 49 ) . '...' : $search_results->post->post_title;
            $return[] = array( $search_results->post->ID, $title ); // array( Post ID, Post Title )
        endwhile;
    endif;
    wp_send_json( $return );
}

// {$taxonomy}_add_form_fields

// HTML output for edit field
add_action('product_cat_add_form_fields', 'ex_product_cat_feature_posts', 10, 1);
add_action('product_cat_edit_form_fields', 'ex_product_cat_feature_posts', 10, 1);
function ex_product_cat_feature_posts( $taxonomy ) {
    // Nonce field to validate form request came from current site
    wp_nonce_field( basename( __FILE__ ), '_feature_post_nonce' );

    $html  = '<tr class="form-field">
    <th scope="row" valign="top"><label for="catshort_button_type">Select Feature post:</label></th>
    <td>
        <select id="ex_product_cat_feature_post" name="ex_product_cat_feature_post[]" multiple="multiple" style="width:99%;max-width:25em;">';

    $term_id = isset($_GET['tag_ID']) ? $_GET['tag_ID'] : '';

    if( $feature_post_ids = get_term_meta( $term_id, 'ex_product_cat_feature_post', true ) ) {
        foreach( $feature_post_ids as $post_id ) {
            $title = get_the_title( $post_id );
            // if the post title is too long, truncate it and add "..." at the end
            $title = ( mb_strlen( $title ) > 50 ) ? mb_substr( $title, 0, 49 ) . '...' : $title;
            $html .=  '<option value="' . $post_id . '" selected="selected">' . $title . '</option>';
        }
    }
    $html .= '</select></td></tr>';

    // CSS Output
    ?><style type="text/css">iframe#description_ifr {min-height:220px !important;}</style><?php

    // HTML Output
    echo $html;

    // jQuery Output
    ?><script>
    // multiple select with AJAX search
    jQuery(function($) {
        $('#ex_product_cat_feature_post').select2({
            ajax: {
                url: ajaxurl, // AJAX URL is predefined in WordPress admin
                dataType: 'json',
                delay: 250, // delay in ms while typing when to perform a AJAX search
                data: function (params) {
                    return {
                        q: params.term, // search query
                        action: 'getpostsearch' // AJAX action for admin-ajax.php
                    };
                },
                processResults: function( data ) {
                    var options = [];
                    if ( data ) {
                        // data is the array of arrays, and each of them contains ID and the Label of the option
                        $.each( data, function( index, text ) { // do not forget that "index" is just auto incremented value
                            options.push( { id: text[0], text: text[1]  } );
                        });
                    }
                    return {
                        results: options
                    };
                },
                cache: true
            },
            minimumInputLength: 3 // the minimum of symbols to input before perform a search
        });
    });
    </script>
    <?php
}

// edited_{$taxonomy}

// Save extra taxonomy fields callback function.
add_action( 'edited_product_cat', 'ex_product_cat_feature_posts_save', 10, 2 );
add_action( 'create_product_cat', 'ex_product_cat_feature_posts_save', 10, 2 );
function ex_product_cat_feature_posts_save( $term_id, $term_taxonomy_id ) {
    if( isset($_POST['ex_product_cat_feature_post']) && $feature_post_ids = $_POST['ex_product_cat_feature_post'] )
        update_term_meta($term_id, 'ex_product_cat_feature_post', $_POST['ex_product_cat_feature_post']);
}

代码进入您的活动子主题(或活动主题)的 function.php 文件。已测试并有效。