Turn your taxonomy into radio select using WordPress walker function

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:

  1. Remove the current meta box and hook up your own
  2. Write your new meta box function
  3. 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";
  }
}

3 thoughts on “Turn your taxonomy into radio select using WordPress walker function

  1. thanks for the useful post.
    But the selected category are stored in a DB only from the standard metabox with category as checkboxes. How to save the selected radio in DB the new metaboxes and get back after the update page?

    • Hi Alex.

      I don’t quite follow what you are asking. The data gets stored and retrieved, just like any other. The walkers determine how to display the (taxonomy) data on the edit screen. Anywhere else, retrieve and display as usual.

  2. i am getting error in this
    $output .= “\n

    term_id}”>” . ‘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 )) . ”;

    }
    part plzzz solve it..

Comments are closed.