I am trying to replace the categories metabox with what looks and works like the tags metabox because there's too much hierarchy and scrolling to check the appropriate categories and sub-categories isn't an option. So in my case tags'-like metabox is better.
This is how I am doing it:
/*
* Non-hierarchal metabox for categories
* (like the tags metabox)
*
* SOURCES:
* http://wordpress.stackexchange.com/a/50098
* http://wordpress.stackexchange.com/a/49048
* http://wordpress.stackexchange.com/a/48816
*
*/
// De-register categories metabox
add_action( 'admin_menu', 'flatsy_remove_meta_box' );
function flatsy_remove_meta_box() {
remove_meta_box( 'categorydiv', 'post', 'normal' );
}
// Add new taxonomy meta box
add_action( 'add_meta_boxes', 'flatsy_add_custom_cat_meta_box' );
function flatsy_add_custom_cat_meta_box() {
add_meta_box( 'flatsy_categorydiv', 'Categories', 'flatsy_custom_cat_metabox', 'post', 'side', 'core' );
}
// This function determines what displays in your metabox
function flatsy_custom_cat_metabox( $post ) {
$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_name = esc_attr($taxonomy);
$taxonomy = get_taxonomy($taxonomy);
$disabled = !current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '';
?>
<div class="tagsdiv" id="<?php echo $tax_name; ?>">
<div class="jaxtag">
<div class="nojs-tags hide-if-js">
<p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
<textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php echo $disabled; ?>><?php echo get_terms_to_edit( $post->ID, $tax_name ); // textarea_escaped by esc_attr() ?></textarea></div>
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
<div class="ajaxtag hide-if-no-js">
<label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
<div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div>
<p><input type="text" id="new-tag-<?php echo $tax_name; ?>" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
<input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" /></p>
</div>
<p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
<?php endif; ?>
</div>
<div class="tagchecklist"></div>
</div>
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
<p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
<?php endif; ?>
<?php
}
That piece of code works as it should... see...
...except that it isn't saving the category metadata when the post is saved. A little bit of searching revealed that I must be doing something like this:
<?php
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{
// Bail if we're doing an auto save
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// if our nonce isn't there, or we can't verify it, bail
if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;
// now we can actually save the data
$allowed = array(
'a' => array( // on allow a tags
'href' => array() // and those anchors can only have href attribute
)
);
// Make sure your data is set before trying to save it
if( isset( $_POST['my_meta_box_text'] ) )
update_post_meta( $post_id, 'my_meta_box_text', wp_kses( $_POST['my_meta_box_text'], $allowed ) );
if( isset( $_POST['my_meta_box_select'] ) )
update_post_meta( $post_id, 'my_meta_box_select', esc_attr( $_POST['my_meta_box_select'] ) );
// This is purely my personal preference for saving check-boxes
$chk = isset( $_POST['my_meta_box_check'] ) && $_POST['my_meta_box_select'] ? 'on' : 'off';
update_post_meta( $post_id, 'my_meta_box_check', $chk );
}
?>
But as I am dealing with the default functionality (i.e. how/what wordpress already does with tags metabox), I want to know what checks are in place for save_post
for 'category' and 'tag' meta boxes and how WordPress does it by default.
// Save post metadata when a post is saved.
add_action( 'save_post', 'flatsy_save_cat_meta' );
function flatsy_save_cat_meta( $post_id, $post, $update ) {
return 'WHAT DO I DO HERE? HOW DOES WORDPRESS DO IT FOR THE TAGS METABOX?';
}
AND if that's not how it's done, what should the code look like when I am converting the category metabox to look like a tag metabox and vice-versa (two cases)?
CLARIFICATION: I don't want to change Categories from hierarchical to non-hierarchical. I just want a tags-like metabox for categories. If I wanted a non-hierarchical taxonomy I'd simply have registered a custom taxonomy.