I have been beating my brains on this one for days now and my Google-fu is failing me.

I have created a custom meta box with a dropdown menu that lists all of the terms from a custom taxonomy. What I cannot figure out is how to save the selected option from the drop down menu when the post is saved. I'm a bit of a newb in PHP and though I have found plenty of tutorials and other questions that talk about how to do this, I always get baffled when they get to the part about saving the data.

Here's my code to create the metabox:

function MC_Catalog_create() {
    add_meta_box( 'MC_Catalog_meta', 'Course Information', 'MC_Catalog_course_info','mc_course_post', 'normal', 'high' );

function MC_Catalog_course_info( $post ) {

$MC_Catalog_course_area = get_post_meta( $post->ID, '_MC_Catalog_course_area', true );
$MC_Catalog_course_num = get_post_meta( $post->ID, '_MC_Catalog_course_num', true );
$MC_Catalog_course_name = get_post_meta( $post->ID, '_MC_Catalog_course_name', true );
$MC_Catalog_course_desc = get_post_meta( $post->ID, '_MC_Catalog_course_desc', true );

<table class="form-table" style="width:auto;">
        <td valign="top">Course Area:</td>
        <td valign="top">
        <select name="MC_Catalog_course_area">
           $myterms = get_terms('course_areas', $args);
                $args = array('orderby'=>'name','order'=>'ASC','hide_empty'=>false);
            foreach($myterms as $term){
                echo "<option value='$term->term_id'" . selected( $term->term_id, $MC_Catalog_course_area, false) .">" . esc_html( $term->name ) . "</option>";
        <td valign="top">Course Number:</td>
        <td valign="top"><input name="MC_Catalog_course_num" type="text" value="<?php echo esc_attr( $MC_Catalog_course_num ); ?>" size="50" /></td>
        <td valign="top">Course Title:</td>
        <td valign="top"><input type="text" name="MC_Catalog_course_name" value="<?php echo esc_attr( $MC_Catalog_course_name ); ?>" size="50" /></td>
        <td valign="top">Course Description:</td>
        <td valign="top"><textarea name="MC_Catalog_course_desc" rows="8" cols="100"><?php echo esc_attr( $MC_Catalog_course_desc ); ?></textarea></td>
<?php } ?>

And here's my code to save the metadata:

//hook to save the meta box data
add_action( 'save_post', 'MC_Catalog_save_meta' );

function MC_Catalog_save_meta( $post_id ) {

    //verify the meta data is set
    if ( isset( $_POST['MC_Catalog_course_num'] ) ) {

        //save the meta data
        update_post_meta( $post_id, '_MC_Catalog_course_area', strip_tags( $_POST['MC_Catalog_course_area'] ) );
    update_post_meta( $post_id, '_MC_Catalog_course_num', strip_tags( $_POST['MC_Catalog_course_num'] ) );
    update_post_meta( $post_id, '_MC_Catalog_course_name', strip_tags( $_POST['MC_Catalog_course_name'] ) );
    update_post_meta( $post_id, '_MC_Catalog_course_desc', strip_tags( $_POST['MC_Catalog_course_desc'] ) );
  • Have you seen this example? It does almost the same, just with another post type instead of a taxonomy.
    – fuxia
    Commented May 10, 2013 at 16:47
  • @toscho I think that code would answer my question, but I'm still a little mystified as to how it works. The bit that goes from if (! $posts) through echo html; just isn't quite clear to me yet. I'm getting close to understanding it. Can you walk me through what each bit is doing there?
    – Burgon
    Commented May 10, 2013 at 17:39

1 Answer 1


$myterms = get_terms($taxonomies, $args); returns an array of term objects. Use $term->term_id as option value …

"<option value='$term->term_id'>". esc_html( $term_name ) . "</option>"

… and store that ID, not the name. Names can change, the IDs will stay the same – unless someone deletes a term and creates a new one with the same name.

To select the correct option use selected():

"<option value='$term->term_id'" . selected( $term->term_id, $MC_Catalog_course_area, FALSE ) .">"

You can validate the value with absint() then.

Your save_post handler needs more checks.

  • Okay - I've updated my original post to include using the ID instead of the name as the value. The HTML it prints out is beautiful, but I still can't figure out how to save that value into my metadata. How do I store the selected option's value when the post is saved?
    – Burgon
    Commented May 10, 2013 at 18:18
  • I take it back. The data is being saved correctly - I just checked the database tables. The problem is, its not setting the default option to the saved option. I thought that's what my If statement was supposed to be doing.
    – Burgon
    Commented May 10, 2013 at 18:33
  • @TommyParker See my update.
    – fuxia
    Commented May 10, 2013 at 18:36
  • Thanks. I worked it out after reading up on the selected() function and simplifying everything a little more. I really appreciate your help today.
    – Burgon
    Commented May 10, 2013 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.