So I’m trying to get WordPress to display the categories as a series of select boxes in a custom meta box and am using some examples from this tutorial, but when I go to save the selection it generates additional categories in the form of the intended selections ID. It also fails to save more than one selection.
<?php
// Add the Meta Box
function add_custom_meta_box() {
add_meta_box(
'custom_meta_box', // $id
'Custom Meta Box', // $title
'show_custom_meta_box', // $callback
'products', // $page
'normal', // $context
'high'); // $priority
}
add_action('add_meta_boxes', 'add_custom_meta_box');
// Field Array
$prefix = 'custom_';
$custom_meta_fields = array(
array(
'label' => 'Category',
'id' => 'category',
'type' => 'tax_checkbox'
) );
// The Callback
function show_custom_meta_box() {
global $custom_meta_fields, $post;
// Use nonce for verification
echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';
// Begin the field table and loop
echo '<table class="form-table">';
foreach ($custom_meta_fields as $field) {
// get value of this field if it exists for this post
$meta = get_post_meta($post->ID, $field['id'], true);
// begin a table row with
echo '<tr>
<th><label for="'.$field['id'].'">'.$field['label'].'</label></th>
<td>';
switch($field['type']) {
case 'tax_checkbox':
$terms = get_terms($field['id'],'get=all' );
$post_terms = wp_get_object_terms( get_the_ID(), $field['id'] );
$taxonomy = get_taxonomy( $field['id'] );
$checked = $post_terms ? $taxonomy->hierarchical ? $post_terms[0]->term_id : $post_terms[0]->slug : null;
foreach ( $terms as $term ) {
$term_value = $taxonomy->hierarchical ? $term->term_id : $term->slug;
echo '<input type="checkbox" value="' . $term_value . '" name="' . $field['id'] . '[]" id="term-' . $term_value . '"' . checked( $checked, $term_value, false ) . ' /> <label for="term-' . $term_value . '">' . $term->name . '</label><br />';
}
echo '<span class="description">' . $field['desc'] . ' <a href="'.get_bloginfo( 'url' ) . '/wp-admin/edit-tags.php?taxonomy=' . $field['id'] . '&post_type=' . $page . '">Manage ' . $taxonomy->label . '</a></span>';
break;
} //end switch
echo '</td></tr>';
} // end foreach
echo '</table>'; // end table
}
// Save the Data
function save_custom_meta($post_id) {
global $custom_meta_fields;
// verify nonce
if (!wp_verify_nonce($_POST['custom_meta_box_nonce'], basename(__FILE__)))
return $post_id;
// check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
// check permissions
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id))
return $post_id;
} elseif (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
// loop through fields and save the data
foreach ($custom_meta_fields as $field) {
if($field['type'] == 'tax_select') continue;
if( in_array( $field['type'], array( 'tax_checkboxes' ) ) ) {
// save taxonomies
if ( isset( $_POST[$field['id']] ) ) {
$term = $_POST[$field['id']];
wp_set_object_terms( $post_id, $term, $field['id'] );
}
}
else {
$old = get_post_meta($post_id, $field['id'], true);
$new = $_POST[$field['id']];
if ($new && $new != $old) {
update_post_meta($post_id, $field['id'], $new);
} elseif ('' == $new && $old) {
delete_post_meta($post_id, $field['id'], $old);
}
} } // end foreach
// save taxonomies
$post = get_post($post_id);
$category = $_POST['category'];
wp_set_object_terms( $post_id, $category, 'category' );
}
add_action('save_post', 'save_custom_meta');
?>
You need to make sure you cast all the terms as integers. Passing in strings will compare the id’s to the slugs, and end up creating new terms with the ids as the name.
Edit
Specifically, alter these two lines as follows (note the
intval
):