Mostrar una taxonomía personalizada como menú desplegable en la página de edición de entradas
Cuando creas una taxonomía personalizada, aparentemente las únicas opciones son mostrarla como etiqueta (no jerárquica) o categoría (jerárquica). ¿Existe alguna manera de mostrarlas como un menú desplegable?
Me doy cuenta de que esto se puede hacer usando add_meta_box()
y agregándolo manualmente, pero estoy buscando una forma incorporada (si existe) ¡para ahorrar mucho código! Gracias.

Puedes agregar una nueva taxonomía con tu propio metabox desde WordPress 3.8 usando meta_box_cb
"drop_cat()" - consiste en reconstruir el metabox de categoría original del núcleo 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 );
}
// Conectar a la acción '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' />"; // Permite enviar un conjunto de términos vacío. 0 es un ID de término inválido y será ignorado por las comprobaciones 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
}

Esto funcionó bien para mí, pero necesité hacer un ajuste en el código para 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' ); ?>

Aquí lo tienes:
<select>
<?php
// Obtener los términos de la taxonomía, incluyendo los vacíos
$tax_terms = get_terms('nombre_de_tu_taxonomia', array('hide_empty' => '0'));
foreach ( $tax_terms as $tax_term ):
// Mostrar cada término como una opción del select
echo '<option value="'.$tax_term->name.'">'.$tax_term->name.'</option>';
endforeach;
?>
</select>
Elimina el segundo argumento de $tax_terms si no deseas mostrar los términos vacíos.
También usa selected si quieres guardar la opción seleccionada :)

Desafortunadamente no hay forma de hacer esto con wp_register_taxonomy()
. Cuando registras una taxonomía, el metabox predeterminado es ya sea casillas de verificación (jerárquico) o como una nube (no jerárquico).
La única solución es desregistrar el metabox existente y añadir uno nuevo en su lugar. Al imitar cuidadosamente el metabox 'predeterminado', no tendrás que procesar los datos manualmente, sino dejar que WordPress maneje automáticamente la adición/eliminación de términos.
Los detalles sobre cómo hacer esto se dan en esta respuesta. También puedes encontrar útil este repositorio de GitHub (que ahora incluye la capacidad de crear términos sobre la marcha en el nuevo metabox). Los recursos enlazados se refieren a crear un metabox con botones de radio, pero podría adaptarse fácilmente para menús desplegables.

Tenía dificultades con el código proporcionado por Alexufo, así que lo reescribí basándome en la función actualizada en WP 4.1.2. Aquí está mi función drop_cat actualizada:
//función reutilizada de 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 //eliminé las pestañas para mostrar solo lo más reciente aquí ?>
<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' />"; // Permite enviar un conjunto de términos vacío. 0 es un ID de término inválido y será ignorado por las comprobaciones 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' => "Seleccionar $tax_name" ) ); ?>
</div>
<?php if ( current_user_can( $taxonomy->cap->edit_terms ) ) :
// eliminé el código para agregar términos aquí dinámicamente, porque hacerlo agregaba un checkbox encima del menú desplegable, el menú desplegable necesitaría ser renderizado nuevamente dinámicamente para mostrar el término recién agregado ?>
<?php endif; ?>
<p><a href="<?php echo site_url(); ?>/wp-admin/edit-tags.php?taxonomy=<?php echo $tax_name ?>&post_type=TU_TIPO_DE_POST">Agregar Nuevo</a></p>
</div>
<?php
}
El único problema que tengo (como indico en mis comentarios en la función anterior), es que no puedo usar la función central de WP para agregar términos/categorías en el meta box, porque por defecto agrega dinámicamente nuevos términos como un checkbox encima de mi menú desplegable. Para que funcione con un menú desplegable, el menú necesitaría ser renderizado nuevamente después de agregar el nuevo término. Algo que estoy seguro que podría resolver pero dejaré para otro día.

El código anterior tenía algunos problemas para mí, permíteme colocar el código correcto que me funcionó
'meta_box_cb' => 'drop_cat',
en tu definición de categoría, luego coloca este código aquí
recuerda incluir
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 //quitamos las pestañas para la versión más reciente aquí ?>
<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' />"; // Permite enviar un conjunto de términos vacío. 0 es un ID de término inválido y será ignorado por las comprobaciones 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' => "Seleccionar $tax_name" ) ); ?>
</div>
<?php if ( current_user_can( $taxonomy->cap->edit_terms ) ) :
// eliminé el código para agregar términos dinámicamente porque al hacerlo se añadía un checkbox sobre el menú desplegable, el menú necesitaría ser renderizado nuevamente dinámicamente para mostrar el nuevo término ?>
<?php endif; ?>
<p><a href="<?php echo site_url(); ?>/wp-admin/edit-tags.php?taxonomy=<?php echo $tax_name ?>&post_type=TU_TIPO_DE_POST">Añadir Nuevo</a></p>
</div>
<?php
}
