Отображение пользовательской таксономии как выпадающего списка на странице редактирования записей
Когда вы создаете пользовательскую таксономию, кажется, что единственные варианты отображения - это метки (не иерархические) или категории (иерархические). Существует ли способ отобразить их в виде выпадающего меню?
Я понимаю, что это можно сделать с помощью add_meta_box()
и фактически добавить вручную, но я ищу встроенный способ (если такой существует), чтобы избежать написания большого количества кода! Спасибо.

Вы можете добавить новую таксономию с собственным метабоксом, начиная с версии WordPress 3.8, используя параметр meta_box_cb.
"drop_cat()" - содержит переработанный оригинальный метабокс категорий из ядра WordPress wp-admin/includes/meta-boxes.php
function realty_type() {
$args = array(
'show_ui' => true,
'meta_box_cb' => 'drop_cat',
);
register_taxonomy( 'realty_type', array( 'YOUR_POST_TYPE' ), $args );
}
// Подключаемся к действию 'init'
add_action( 'init', 'realty_type', 0 );
function drop_cat( $post, $box ) {
$defaults = array('taxonomy' => 'category');
if ( !isset($box['args']) || !is_array($box['args']) )
$args = array();
else
$args = $box['args'];
extract( wp_parse_args($args, $defaults), EXTR_SKIP );
$tax = get_taxonomy($taxonomy);
?>
<div id="taxonomy-<?php echo $taxonomy; ?>" class="acf-taxonomy-field categorydiv">
<?php
$name = ( $taxonomy == 'category' ) ? 'post_category' : 'tax_input[' . $taxonomy . ']';
echo "<input type='hidden' name='{$name}[]' value='0' />"; // Позволяет отправить пустой набор терминов. 0 - неверный ID термина и будет проигнорирован проверками empty().
?>
<? $term_obj = wp_get_object_terms($post->ID, $taxonomy ); //_log($term_obj[0]->term_id)?>
<ul id="<?php echo $taxonomy; ?>checklist" data-wp-lists="list:<?php echo $taxonomy?>" class="categorychecklist form-no-clear">
<?php //wp_terms_checklist($post->ID, array( 'taxonomy' => $taxonomy) ) ?>
</ul>
<?php wp_dropdown_categories( array( 'taxonomy' => $taxonomy, 'hide_empty' => 0, 'name' => "{$name}[]", 'selected' => $term_obj[0]->term_id, 'orderby' => 'name', 'hierarchical' => 0, 'show_option_none' => '—' ) ); ?>
</div>
<?php
}

Это сработало для меня, но мне потребовалось внести небольшую правку в код для WordPress 4.9.5 ... <?php wp_dropdown_categories( 'taxonomy' => $taxonomy, 'hide_empty' => 0, 'name' => "{$name}[]", 'selected' => $term_obj[0]->name, 'orderby' => 'name', 'hierarchical' => 0, 'show_option_none' => '—','option_none_value'=> '0', 'value_field' => 'name' ); ?>

Вот решение:
<select>
<?php
// Получаем все термины таксономии, включая пустые
$tax_terms = get_terms('your_taxonomy_name', array('hide_empty' => '0'));
foreach ( $tax_terms as $tax_term ):
// Выводим каждый термин как option в select
echo '<option value="'.$tax_term->name.'">'.$tax_term->name.'</option>';
endforeach;
?>
</select>
Удалите второй аргумент $tax_terms, если не хотите отображать пустые термины.
Также используйте selected, если нужно сохранять выбранную опцию :)

К сожалению, невозможно сделать это с помощью функции wp_register_taxonomy()
. При регистрации таксономии стандартный метабокс представляет собой либо чекбоксы (для иерархических таксономий), либо облако тегов (для неиерархических).
Единственный способ обойти это — отменить регистрацию существующего метабокса и добавить новый на его месте. Тщательно имитируя «стандартный» метабокс, вам не придется обрабатывать данные вручную, а WordPress автоматически будет управлять добавлением/удалением терминов.
Подробности о том, как это сделать, приведены в этом ответе. Также вам может быть полезен этот репозиторий на GitHub (который теперь включает возможность создания терминов на лету в новом метабоксе). В указанных ресурсах рассматривается создание метабокса с радиокнопками, но его можно легко адаптировать для выпадающих меню.

У меня возникли сложности с кодом, предоставленным Alexufo, поэтому я переписал его на основе обновленной функции в WP 4.1.2. Вот моя обновленная функция drop_cat:
// функция ниже переработана из wp-admin/includes/meta-boxes.php - post_categories_meta_box()
function drop_cat( $post, $box ) {
$defaults = array( 'taxonomy' => 'category' );
if ( ! isset( $box['args'] ) || ! is_array( $box['args'] ) ) {
$args = array();
} else {
$args = $box['args'];
}
$r = wp_parse_args( $args, $defaults );
$tax_name = esc_attr( $r['taxonomy'] );
$taxonomy = get_taxonomy( $r['taxonomy'] );
?>
<div id="taxonomy-<?php echo $tax_name; ?>" class="categorydiv">
<?php // убрал вкладки для последних записей здесь ?>
<div id="<?php echo $tax_name; ?>-all">
<?php
$name = ( $tax_name == 'category' ) ? 'post_category' : 'tax_input[' . $tax_name . ']';
echo "<input type='hidden' name='{$name}[]' value='0' />"; // Позволяет отправлять пустой набор терминов. 0 является недопустимым ID термина и будет игнорироваться проверками empty().
?>
<ul id="<?php echo $tax_name; ?>checklist" data-wp-lists="list:<?php echo $tax_name; ?>" class="categorychecklist form-no-clear">
<?php //wp_terms_checklist( $post->ID, array( 'taxonomy' => $tax_name, 'popular_cats' => $popular_ids ) ); ?>
</ul>
<?php $term_obj = wp_get_object_terms($post->ID, $tax_name ); //_log($term_obj[0]->term_id) ?>
<?php wp_dropdown_categories( array( 'taxonomy' => $tax_name, 'hide_empty' => 0, 'name' => "{$name}[]", 'selected' => $term_obj[0]->term_id, 'orderby' => 'name', 'hierarchical' => 0, 'show_option_none' => "Выбрать $tax_name" ) ); ?>
</div>
<?php if ( current_user_can( $taxonomy->cap->edit_terms ) ) :
// удалил код для динамического добавления терминов, так как это добавляло чекбокс над новым выпадающим меню, меню нужно будет перерисовывать динамически для отображения нового термина ?>
<?php endif; ?>
<p><a href="<?php echo site_url(); ?>/wp-admin/edit-tags.php?taxonomy=<?php echo $tax_name ?>&post_type=YOUR_POST_TYPE">Добавить новый</a></p>
</div>
<?php
}
Одна проблема, с которой я столкнулся (как указано в моих комментариях к функции выше), заключается в том, что я не могу использовать стандартную функцию WordPress для добавления терминов/категорий в метабоксе, так как по умолчанию новые термины добавляются динамически как чекбокс над моим выпадающим меню. Чтобы работать с выпадающим меню, его потребуется перерисовывать после добавления нового термина. Я уверен, что смогу разобраться с этим, но оставлю это на другой день.

В приведенном выше коде у меня были некоторые проблемы, позвольте мне привести правильный код, который сработал у меня
'meta_box_cb' => 'drop_cat',
ваше определение категории, затем вставьте этот код здесь
не забудьте добавить
function drop_cat( $post, $box ) {
if ( ! isset( $box['args'] ) || ! is_array( $box['args'] ) ) {
$args = array();
} else {
$args = $box['args'];
}
$r = wp_parse_args( $args, $defaults );
$tax_name = esc_attr( $r['taxonomy'] );
$taxonomy = get_taxonomy( $r['taxonomy'] );
?>
<div id="taxonomy-<?php echo $tax_name; ?>" class="categorydiv">
<?php //убрал вкладки для последних записей здесь ?>
<div id="<?php echo $tax_name; ?>-all">
<?php
$name = ( $tax_name == 'category' ) ? 'post_category' : 'tax_input[' . $tax_name . ']';
echo "<input type='hidden' name='{$name}[]' value='0' />"; // Позволяет отправить пустой набор терминов. 0 является недопустимым ID термина и будет проигнорирован проверками empty().
?>
<ul id="<?php echo $tax_name; ?>checklist" data-wp-lists="list:<?php echo $tax_name; ?>" class="categorychecklist form-no-clear">
<?php //wp_terms_checklist( $post->ID, array( 'taxonomy' => $tax_name, 'popular_cats' => $popular_ids ) ); ?>
</ul>
<?php $term_obj = wp_get_object_terms($post->ID, $tax_name ); //_log($term_obj[0]->term_id)
?>
<?php wp_dropdown_categories( array( 'taxonomy' => $tax_name, 'option_none_value' => 0 ,'id'=>$term_obj[0]->term_id, 'value_field'=> 'slug' , 'hide_empty' => 0, 'name' => "{$name}[]", 'selected' => $term_obj[0]->slug, 'orderby' => 'name', 'hierarchical' => 0, 'show_option_none' => "Выбрать $tax_name" ) ); ?>
</div>
<?php if ( current_user_can( $taxonomy->cap->edit_terms ) ) :
// удалил код для динамического добавления терминов, так как это добавляло флажок над новым выпадающим меню, а выпадающее меню нужно было бы перерисовывать динамически для отображения нового термина ?>
<?php endif; ?>
<p><a href="<?php echo site_url(); ?>/wp-admin/edit-tags.php?taxonomy=<?php echo $tax_name ?>&post_type=YOUR_POST_TYPE">Добавить новый</a></p>
</div>
<?php
}
