WordPress分类单选按钮

时间:2014-03-26 作者:Maartje

我正在尝试将后端的术语复选框更改为单选按钮。我找到了这个主题:Altering the appearance of custom taxonomy inputs 然而,威奇帮助我做到了这一点。但是,这会将所有术语复选框变成单选按钮。

是否可以仅将此应用于一种分类法?

我的代码:

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;
}
谢谢

4 个回复
最合适的回答,由SO网友:TheDeadMedic 整理而成

但是,这会将所有术语复选框变成单选按钮。

不仅如此,它还会在元框中打开任何复选框-这并不理想!

相反,让我们专门针对wp_terms_checklist() 函数,用于生成整个管理员的复选框列表(包括快速编辑)。

/**
 * 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\' );
我们抓住了wp_terms_checklist_args 过滤,然后实现我们自己的自定义“walker”(用于生成层次列表的一系列类)。从这里开始,它只是一个字符串替换type="checkbox" 具有type="radio" 如果分类法是我们配置为匹配的(在本例中为“类别”)。

SO网友:Nicolai Grossherr

以下内容与@TheDeadMedic在他的answer 很好的回答,让我半途而废,所以这只是一种补充。出于个人喜好,我选择了start_el.

→ 确保根据需要在下面的代码中替换YOUR-TAXONOMY

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;
}
现在正确地称为“Howdy\\u McGee”stated in his comment 这在快速/内联编辑中无法正常工作。上面的代码正确地处理了保存操作,但未选中内联编辑处的单选项。当然,我们希望如此,为此,我已经做到了:

→ 编写一些JQuery代码来处理选中状态
→ 文件名:editphp inline edit tax radio hack。js-以下用于排队

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\' );
            }
        });
    });

});
→ 我们需要一个AJAX操作-如上面的代码块所示

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();
}
→ 在脚本上方排队
→ 根据需要更改路径信息

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\' )
    );
}
到目前为止,这一切都很顺利,but 只有第一次,当第二次打开内联编辑时,我们再次丢失了选中状态。我们显然不希望这样。为了解决这个问题,我使用了我找到的一种方法here 作者:brasofilo。它所做的是重新加载更新的内联编辑节。这会正确显示收音机复选框,无论其更改频率如何。

→ 请确保根据您的需要在下面的代码中替换您的-POST-TYPE

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();
}


注:未进行广泛测试,但目前运行良好

SO网友:BdN3504

您可以使用meta_box_cb 的参数register_taxonomy 函数为meta_box. 借助于此article 我创建了以下代码段:

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
}
要使用此meta\\u框,必须将此参数传递给register_taxonomy 功能:

\'meta_box_cb\'                => \'YOUR_TAXONOMY_NAME_meta_box\'
这段代码的美妙之处在于,您根本不需要传入任何参数,因为它依赖于register_taxonomy 作用这些是post 对象和包含元数据库本身信息的数组。

SO网友:patilswapnilv

如果您更愿意让它与插件一起工作,您可能想看看https://wordpress.org/plugins/radio-buttons-for-taxonomies/

该插件允许您使用使用单选按钮的自定义元框替换默认的分类框……有效地将每个帖子限制为该分类中的单个术语。

结束

相关推荐

如何避免WebDevStudio的WDS_Taxonomy_Radio分类Metabox类出现Foreach错误?

使用WebDevStudio的WDS\\U Taxonomy\\U Radio Taxonomy metabox类的正确方法是什么?我已经在函数中包含了代码。php文件,但我收到一个错误,错误如下:*为foreach()WDS\\u Taxonomy\\u Radio提供的参数无效。班php第45行*所以我一定是做错了什么。GitHub上的说明是:初始化类(用自己的更新分类slug)使用代码$custom_tax_mb = new WDS_Taxonomy_Radio( \'custom-tax-slug