Các nút radio phân loại WordPress


8

Tôi đang cố gắng thay đổi các hộp kiểm cho các điều khoản trên phụ trợ thành radiobuttons. Tôi tìm thấy chủ đề này: Thay đổi sự xuất hiện của các đầu vào phân loại tùy chỉnh tuy nhiên tôi đã giúp tôi làm điều này. Tuy nhiên, điều này sẽ biến TẤT CẢ các hộp kiểm điều khoản thành các nút radio.

Có thể áp dụng điều này chỉ cho một nguyên tắc phân loại?

Mã của tôi:

add_action('add_meta_boxes','mysite_add_meta_boxes',10,2);
function mysite_add_meta_boxes($post_type, $post) {
  ob_start();
}
add_action('dbx_post_sidebar','mysite_dbx_post_sidebar');
function mysite_dbx_post_sidebar() {
  $html = ob_get_clean();
  $html = str_replace('"checkbox"','"radio"',$html);
  echo $html;
}

cảm ơn

Câu trả lời:


13

Tuy nhiên, điều này sẽ biến TẤT CẢ các hộp kiểm điều khoản thành các nút radio.

Không chỉ vậy, nó sẽ biến bất kỳ hộp kiểm nào trong hộp meta - không lý tưởng!

Thay vào đó, hãy nhắm mục tiêu cụ thể wp_terms_checklist()chức năng, được sử dụng để tạo danh sách các hộp kiểm trên toàn quản trị viên (bao gồm chỉnh sửa nhanh).

/**
 * Use radio inputs instead of checkboxes for term checklists in specified taxonomies.
 *
 * @param   array   $args
 * @return  array
 */
function wpse_139269_term_radio_checklist( $args ) {
    if ( ! empty( $args['taxonomy'] ) && $args['taxonomy'] === 'category' /* <== Change to your required taxonomy */ ) {
        if ( empty( $args['walker'] ) || is_a( $args['walker'], 'Walker' ) ) { // Don't override 3rd party walkers.
            if ( ! class_exists( 'WPSE_139269_Walker_Category_Radio_Checklist' ) ) {
                /**
                 * Custom walker for switching checkbox inputs to radio.
                 *
                 * @see Walker_Category_Checklist
                 */
                class WPSE_139269_Walker_Category_Radio_Checklist extends Walker_Category_Checklist {
                    function walk( $elements, $max_depth, ...$args ) {
                        $output = parent::walk( $elements, $max_depth, ...$args );
                        $output = str_replace(
                            array( 'type="checkbox"', "type='checkbox'" ),
                            array( 'type="radio"', "type='radio'" ),
                            $output
                        );

                        return $output;
                    }
                }
            }

            $args['walker'] = new WPSE_139269_Walker_Category_Radio_Checklist;
        }
    }

    return $args;
}

add_filter( 'wp_terms_checklist_args', 'wpse_139269_term_radio_checklist' );

Chúng tôi nối vào wp_terms_checklist_argsbộ lọc, sau đó triển khai "walker" tùy chỉnh của riêng chúng tôi (một nhóm các lớp được sử dụng để tạo danh sách phân cấp). Từ đó, nó đơn giản là một chuỗi thay thế type="checkbox"bằng type="radio"nếu phân loại là bất cứ điều gì chúng ta đã cấu hình nó phù hợp (trong trường hợp này là "thể loại").


2
Coi chừng , đây là một câu trả lời tuyệt vời nhưng đặt ra một vấn đề cho Chỉnh sửa nhanh. Mặc dù nó chuyển đổi các hộp kiểm chỉnh sửa nhanh thành các nút radio nhưng nó không chọn radio đã chọn, thay vào đó, nó sẽ xóa danh sách. Nếu bạn chỉnh sửa nhanh, bạn phải kiểm tra danh mục mỗi lần nếu không nó sẽ bị xóa.
Howdy_McGee

1
@Howdy_McGee Xem câu trả lời của tôi cho cách tiếp cận với một số thay đổi bổ sung để khắc phục giới hạn.
Nicolai

Chỉnh sửa nhanh về giá trị gán danh mục không được đặt. Vui lòng hướng dẫn chúng tôi
ravi patel

Đây là một điều chỉnh nhỏ cần được thực hiện cho WP v5.3 trở lên: function walk( $elements, $max_depth, ...$args ) { $output = parent::walk( $elements, $max_depth, ...$args ); Hai dòng đó cần phải có các hình elip được đặt ở phía trước $argshoặc nó sẽ gây ra lỗi. Tôi sẽ cố gắng chỉnh sửa câu trả lời ở trên ...
Tony Djukic

3

Phần sau đây thực hiện khá nhiều những gì @TheDeadMedic đã trả lời câu trả lời hay của anh ấy , đưa tôi đến đó một nửa, vì vậy đây chỉ là một bổ sung cho nó. Ngoài sở thích cá nhân tôi đã chọn để làm điều đó với start_el.

→ đảm bảo thay thế THUẾ CỦA BẠN theo mã bên dưới theo nhu cầu của bạn

add_filter( 'wp_terms_checklist_args', 'wpse_139269_term_radio_checklist_start_el_version', 10, 2 );
function wpse_139269_term_radio_checklist_start_el_version( $args, $post_id ) {
    if ( ! empty( $args['taxonomy'] ) && $args['taxonomy'] === 'YOUR-TAXONOMY' ) {
        if ( empty( $args['walker'] ) || is_a( $args['walker'], 'Walker' ) ) { // Don't override 3rd party walkers.
            if ( ! class_exists( 'WPSE_139269_Walker_Category_Radio_Checklist_Start_El_Version' ) ) {
                class WPSE_139269_Walker_Category_Radio_Checklist_Start_El_Version extends Walker_Category_Checklist {
                    public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
                        if ( empty( $args['taxonomy'] ) ) {
                            $taxonomy = 'category';
                        } else {
                            $taxonomy = $args['taxonomy'];
                        }

                        if ( $taxonomy == 'category' ) {
                            $name = 'post_category';
                        } else {
                            $name = 'tax_input[' . $taxonomy . ']';
                        }

                        $args['popular_cats'] = empty( $args['popular_cats'] ) ? array() : $args['popular_cats'];
                        $class = in_array( $category->term_id, $args['popular_cats'] ) ? ' class="popular-category"' : '';

                        $args['selected_cats'] = empty( $args['selected_cats'] ) ? array() : $args['selected_cats'];

                        /** This filter is documented in wp-includes/category-template.php */
                        if ( ! empty( $args['list_only'] ) ) {
                            $aria_cheched = 'false';
                            $inner_class = 'category';

                            if ( in_array( $category->term_id, $args['selected_cats'] ) ) {
                                $inner_class .= ' selected';
                                $aria_cheched = 'true';
                            }

                            $output .= "\n" . '<li' . $class . '>' .
                                '<div class="' . $inner_class . '" data-term-id=' . $category->term_id .
                                ' tabindex="0" role="checkbox" aria-checked="' . $aria_cheched . '">' .
                                esc_html( apply_filters( 'the_category', $category->name ) ) . '</div>';
                        } else {
                            $output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
                            '<label class="selectit"><input value="' . $category->term_id . '" type="radio" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' .
                            checked( in_array( $category->term_id, $args['selected_cats'] ), true, false ) .
                            disabled( empty( $args['disabled'] ), false, false ) . ' /> ' .
                            esc_html( apply_filters( 'the_category', $category->name ) ) . '</label>';
                        }
                    }
                }
            }
            $args['walker'] = new WPSE_139269_Walker_Category_Radio_Checklist_Start_El_Version;
        }
    }
    return $args;
}

Bây giờ như @ Howdy_McGee đã nêu chính xác trong nhận xét của mình, điều này không hoạt động tốt, chính xác với chỉnh sửa nhanh / nội tuyến. Đoạn mã trên xử lý việc lưu chính xác, nhưng radio ở phần chỉnh sửa nội tuyến không được kiểm tra. Tất nhiên chúng tôi muốn điều đó, vì điều này tôi đã làm điều này:

→ viết một số mã JQuery để xử lý trạng thái đã kiểm tra
→ tên tệp: editphp-inline-edit-tax-radio-hack.js - được sử dụng bên dưới để ghi danh

jQuery(document).ready(function($) {
    var taxonomy = 'status',
        post_id = null,
        term_id = null,
        li_ele_id = null;
    $('a.editinline').on('click', function() {
        post_id = inlineEditPost.getId(this);
        $.ajax({
            url: ajaxurl,
            data: {
                action: 'wpse_139269_inline_edit_radio_checked_hack',
                'ajax-taxonomy': taxonomy,
                'ajax-post-id': post_id
            },
            type: 'POST',
            dataType: 'json',
            success: function (response) {
                term_id = response;
                li_ele_id = 'in-' + taxonomy + '-' + term_id;
                $( 'input[id="'+li_ele_id+'"]' ).attr( 'checked', 'checked' );
            }
        });
    });

});

→ chúng ta cần một hành động AJAX - như đã thấy trong khối mã ở trên

add_action( 'wp_ajax_wpse_139269_inline_edit_radio_checked_hack', 'wpse_139269_inline_edit_radio_checked_hack' );
add_action( 'wp_ajax_nopriv_wpse_139269_inline_edit_radio_checked_hack', 'wpse_139269_inline_edit_radio_checked_hack' );
function wpse_139269_inline_edit_radio_checked_hack() {
    $terms = wp_get_object_terms(
        $_POST[ 'ajax-post-id' ],
        $_POST[ 'ajax-taxonomy' ],
        array( 'fields' => 'ids' )
    );
    $result = $terms[ 0 ];
    echo json_encode($result);
    exit;
    die();
}

→ enqueueing script phía trên
→ thay đổi thông tin đường dẫn theo nhu cầu của bạn

add_action( 'admin_enqueue_scripts', 'wpse_139269_inline_edit_radio_checked_hack_enqueue_script' );
function wpse_139269_inline_edit_radio_checked_hack_enqueue_script() {
    wp_enqueue_script(
        'editphp-inline-edit-tax-radio-hack-js',
        get_template_directory_uri() . '/your/path/editphp-inline-edit-tax-radio-hack.js',
        array( 'jquery' )
    );
}

Điều này hoạt động khá độc đáo cho đến nay, nhưng chỉ lần đầu tiên, khi mở chỉnh sửa nội tuyến lần thứ hai, chúng tôi lại mất trạng thái đã kiểm tra. Chúng tôi rõ ràng không muốn điều đó. Để giải quyết vấn đề này, tôi đã sử dụng một phương pháp mà tôi đã tìm thấy ở đây bởi @brasofilo. Những gì nó làm là tải lại phần chỉnh sửa nội tuyến được cập nhật. Điều này dẫn đến hộp kiểm radio được hiển thị chính xác, bất kể tần suất thay đổi.

→ đảm bảo thay thế TY-POST-TYPE theo mã bên dưới theo nhu cầu của bạn

add_action( 'wp_ajax_inline-save', 'wpse_139269_wp_ajax_inline_save', 0 );
function wpse_139269_wp_ajax_inline_save() {
    global $wp_list_table;

    check_ajax_referer( 'inlineeditnonce', '_inline_edit' );

    if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
        wp_die();

        if ( 'page' == $_POST['post_type'] ) {
            if ( ! current_user_can( 'edit_page', $post_ID ) )
                wp_die( __( 'You are not allowed to edit this page.' ) );
        } else {
            if ( ! current_user_can( 'edit_post', $post_ID ) )
                wp_die( __( 'You are not allowed to edit this post.' ) );
        }

        if ( $last = wp_check_post_lock( $post_ID ) ) {
            $last_user = get_userdata( $last );
            $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
            printf( $_POST['post_type'] == 'page' ? __( 'Saving is disabled: %s is currently editing this page.' ) : __( 'Saving is disabled: %s is currently editing this post.' ),    esc_html( $last_user_name ) );
            wp_die();
        }

        $data = &$_POST;

        $post = get_post( $post_ID, ARRAY_A );

        // Since it's coming from the database.
        $post = wp_slash($post);

        $data['content'] = $post['post_content'];
        $data['excerpt'] = $post['post_excerpt'];

        // Rename.
        $data['user_ID'] = get_current_user_id();

        if ( isset($data['post_parent']) )
            $data['parent_id'] = $data['post_parent'];

            // Status.
            if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
                $data['post_status'] = 'private';
            else
                $data['post_status'] = $data['_status'];

            if ( empty($data['comment_status']) )
                $data['comment_status'] = 'closed';
            if ( empty($data['ping_status']) )
                $data['ping_status'] = 'closed';

            // Exclude terms from taxonomies that are not supposed to appear in Quick Edit.
            if ( ! empty( $data['tax_input'] ) ) {
                foreach ( $data['tax_input'] as $taxonomy => $terms ) {
                    $tax_object = get_taxonomy( $taxonomy );
                    /** This filter is documented in wp-admin/includes/class-wp-posts-list-table.php */
                    if ( ! apply_filters( 'quick_edit_show_taxonomy', $tax_object->show_in_quick_edit, $taxonomy, $post['post_type'] ) ) {
                        unset( $data['tax_input'][ $taxonomy ] );
                    }
                }
            }

            // Hack: wp_unique_post_slug() doesn't work for drafts, so we will fake that our post is published.
            if ( ! empty( $data['post_name'] ) && in_array( $post['post_status'], array( 'draft', 'pending' ) ) ) {
                $post['post_status'] = 'publish';
                $data['post_name'] = wp_unique_post_slug( $data['post_name'], $post['ID'], $post['post_status'], $post['post_type'], $post['post_parent'] );
            }

            // Update the post.
            edit_post();

            $wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => $_POST['screen'] ) );

            $level = 0;
            $request_post = array( get_post( $_POST['post_ID'] ) );
            $parent = $request_post[0]->post_parent;

            while ( $parent > 0 ) {
                $parent_post = get_post( $parent );
                $parent = $parent_post->post_parent;
                $level++;
            }

            $wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ), $level );

            if( $_POST['post_type'] == 'YOUR-POST-TYPE' ) {
                ?>
                    <script type="text/javascript">
                        document.location.reload(true);
                    </script>
                <?php
            }

    wp_die();
}



Lưu ý: Không được thử nghiệm rộng rãi, nhưng cho đến nay vẫn hoạt động tốt


1

Bạn có thể sử dụng meta_box_cbtham số của register_taxonomyhàm để xác định hàm riêng cho meta_box. Với sự giúp đỡ của bài viết này, tôi đã tạo ra đoạn trích này:

function YOUR_TAXONOMY_NAME_meta_box($post, $meta_box_properties){
  $taxonomy = $meta_box_properties['args']['taxonomy'];
  $tax = get_taxonomy($taxonomy);
  $terms = get_terms($taxonomy, array('hide_empty' => 0));
  $name = 'tax_input[' . $taxonomy . ']';
  $postterms = get_the_terms( $post->ID, $taxonomy );
  $current = ($postterms ? array_pop($postterms) : false);
  $current = ($current ? $current->term_id : 0);
?>
<div id="taxonomy-<?php echo $taxonomy; ?>" class="categorydiv">
  <ul id="<?php echo $taxonomy; ?>-tabs" class="category-tabs">
    <li class="tabs"><a href="#<?php echo $taxonomy; ?>-all"><?php echo $tax->labels->all_items; ?></a></li>
  </ul>

  <div id="<?php echo $taxonomy; ?>-all" class="tabs-panel">
    <input name="tax_input[<?php echo $taxonomy; ?>][]" value="0" type="hidden">            
    <ul id="<?php echo $taxonomy; ?>checklist" data-wp-lists="list:symbol" class="categorychecklist form-no-clear">
<?php   foreach($terms as $term){
      $id = $taxonomy.'-'.$term->term_id;?>
      <li id="<?php echo $id?>"><label class="selectit"><input value="<?php echo $term->term_id; ?>" name="tax_input[<?php echo $taxonomy; ?>][]" id="in-<?php echo $id; ?>"<?php if( $current === (int)$term->term_id ){?> checked="checked"<?php } ?> type="radio"> <?php echo show_symbol( $term->name ); ?></label></li>
<?php   }?>
    </ul>
  </div>
</div>
<?php
}

Để sử dụng meta_box này, bạn phải truyền tham số này cho register_taxonomyhàm:

'meta_box_cb'                => 'YOUR_TAXONOMY_NAME_meta_box'

Cái hay của mã này là bạn phải truyền không có tham số nào cả, bởi vì nó phụ thuộc vào các tham số được truyền cho nó bởi register_taxonomyhàm. Đây là các postđối tượng và một mảng chứa thông tin trên chính metabox.


0

Nếu bạn muốn làm cho nó hoạt động với một plugin, bạn có thể muốn xem https://wordpress.org/plugins/radio-buttons-for-taxonomies/

Plugin này cho phép bạn thay thế các hộp phân loại mặc định bằng metabox tùy chỉnh sử dụng các nút radio, giới hạn hiệu quả mỗi bài đăng trong một thuật ngữ duy nhất trong phân loại đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.