There are a number of ways in which the WordPress taxonomy system could be extended. One such thing would be to restrict the selection of a taxonomy’s terms to just one term per post. To give a simple example, imagine you wanted to represent some books in some libraries (they are reference books only). Create a book custom post type, and assign it a custom taxonomy library. A book can only ever be in one library.
There are 3 steps to creating radio selectors for your library meta box on the admin screen:
- Remove the current meta box and hook up your own
- Write your new meta box function
- Write a class to extend the walker function for radio boxes
1. Remove core default meta box, and hook in your own.
Note: the meta WordPress hook names and HTML class names differ, depending on whether the taxonomy is a tag or a category (hierarchical).
add_action( 'add_meta_boxes', 'tcb_mb_taxonomy_walkers' );
function tcb_mb_taxonomy_walkers( $post_type ) {
remove_meta_box( 'tagsdiv-library', $post_type, 'side' );
//remove_meta_box( 'library_typesdiv', $post_type, 'side' ); // Category syntax
if( $post_type == 'book' ) :
add_meta_box( 'tagsdiv-library', 'My Books', 'tcb_mb_library', $post_type, 'side' );
//add_meta_box( 'library_typesdiv', 'My Books', 'tcb_mb_library', $post_type, 'side' );
endif;
}
2. Write the new meta box function. Making sure you pass in your new walker into the checklist function.
function tcb_mb_library( $post, $meta_box ) {
$taxonomy = 'library';
$tax = get_taxonomy( $taxonomy );
$selected = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
echo '<div id="taxonomy-' . $taxonomy . '" class="categorydiv">';
echo '<input type="hidden" name="tax_input[' . $taxonomy . '][]" value="0" />';
echo '<ul id="' . $taxonomy . 'checklist" class="list:' . $taxonomy . ' categorychecklist form-no-clear">';
$walker = new tcb_Walker_Category_Radiolist;
wp_terms_checklist( $post->ID, array(
'taxonomy' => $taxonomy,
'selected_cats' => $selected,
'checked_ontop' => false,
'walker' => $walker,
) );
echo '</ul>';
}
3. Extend the core walker class into your own
/** Radio Button Walker */
class tcb_Walker_Category_Radiolist extends Walker {
var $tree_type = 'category';
var $db_fields = array( 'parent'=>'parent', 'id'=>'term_id' );
function start_lvl( &$output, $depth, $args ){
$indent = str_repeat( "\t", $depth );
$output .= "$indent<ul class='children'>\n";
}
function end_lvl( &$output, $depth, $args ){
$indent = str_repeat( "\t", $depth );
$output .= "$indent</ul>\n";
}
function start_el( &$output, $category, $depth, $args ){
extract( $args );
if ( empty($taxonomy) )
$taxonomy = 'category';
if( $taxonomy == 'category' ) :
$name = 'post_category';
else :
$name = 'tax_input[' . $taxonomy . ']';
endif;
$output .= "\n
<ul>
<li id="{$taxonomy}-{$category->term_id}">" . '<label class="selectit"><input value="' . $category->name . '" type="radio" name="'.$name.'" id="in-'.$taxonomy.'-' . $category->term_id . '"' . checked( in_array( $category->term_id, $selected_cats ), true, false ) . ' /> ' . esc_html( apply_filters('the_category', $category->name )) . '</label>';</li>
</ul>
}
function end_el( &$output, $category, $depth, $args ){
$output .= "</li>\n";
}
}