Custom post types is a new and powerful feature in WordPress 3.0. Here, we consider how to add metaboxes to the new custom post type user interface.
There are three general classes of metaboxes that we may add to our custom post type screen –
- Built-in metaboxes – These metaboxes are built-in to custom post types, and can be easily added by calling the add_post_type_support function or by including them in our register_post_type function call.
- Taxonomy metaboxes – These are metaboxes associated with WordPress taxonomy objects. For example, two standard WordPress taxonomy objects are category and post_tag. Both have metaboxes defined, which we can include into our custom post type interface.
- Custom metaboxes – These are fully custom metaboxes that we create specially for our plugins or themes. They will usually contain HTML form elements that allow users to specify additional attributes and data for our custom post types.
1. Built-in Metabox
There are a variety of metaboxes that are built-in to custom post types.
- ‘title’
- ‘editor’ (content)
- ‘author’
- ‘thumbnail’ (featured image) (current theme must also support post-thumbnails)
- ‘excerpt’
- ‘trackbacks’
- ‘custom-fields’
- ‘comments’ (also will see comment count balloon on edit screen
- ‘revisions’ (will store revisions)
- ‘page-attributes’ (template and menu order) (hierarchical must be true)
[List taken from the WordPress Codex]
We can include built-in metaboxes during the creation of our custom post type object –
$labels = array( 'name' => _x('Galleries', 'post type general name'), 'singular_name' => _x('Gallery', 'post type singular name'), 'add_new' => _x('Add New', 'gallery'), 'add_new_item' => __("Add New Gallery"), 'edit_item' => __("Edit Gallery"), 'new_item' => __("New Gallery"), 'view_item' => __("View Gallery"), 'search_items' => __("Search Gallery"), 'not_found' => __('No galleries found'), 'not_found_in_trash' => __('No galleries found in Trash'), 'parent_item_colon' => '' ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'query_var' => true, 'rewrite' => true, 'capability_type' => 'post', 'hierarchical' => false, 'menu_position' => null, 'supports' => array('title','thumbnail','excerpt') ); register_post_type('gallery',$args);
Line 24 – The support argument specifies which of the built-in metaboxes we want to include in our custom post type interface. Here, we include title, thumbnail, excerpt.
We can also include built-in metaboxes by using the add_post_type_support function.
add_post_type_support('gallery', 'title'); add_post_type_support('gallery', array('title', 'thumbnail', 'excerpt') );
The first argument is our custom post type and the second argument is the built-in metabox name(s) (can be a string or an array).
2. Taxonomy Metabox
We can add taxonomy metaboxes (e.g. category, post tag) to our custom post type interface by including them in our register_post_type function call.
$args = array( 'labels' => $labels, ... 'taxonomies' => array('category', 'post_tag') ); register_post_type('gallery',$args);
Alternatively, we may use the register_taxonomy_for_object_type function.
register_taxonomy_for_object_type( 'post_tag', 'gallery'); register_taxonomy_for_object_type( 'category', 'gallery');
Once we register an existing taxonomy with our custom post type, metaboxes are automatically added for that taxonomy. Below, a new Category and Gallery Tag metabox have been added to our custom post interface. The relevant taxonomy inputs will also be automatically saved, when we save our custom post object.
Note – The category and post_tag taxonomy objects each have their own special metabox interface. However, all other taxonomy objects will just use the standard WordPress post_tag interface.
If we want to replace the standard post_tag metabox with our own metabox, we may use the add_meta_box function which we will consider next.
3. Custom Metabox
Here, we create a custom metabox for our gallery object. In particular, we want to add a metabox containing a set of radio buttons so that users may choose what type of objects they want to store in their gallery (i.e. gallery type).
For example, they may only want to store attachments, or they may also want to store posts, pages, and even other galleries.
<?php // Add meta box goes into our admin_init function add_meta_box( 'gallery-type-div', __('Gallery Type'), 'gallery_type_metabox', 'gallery', 'normal', 'low'); function gallery_type_metabox($post) { $gallery_type = get_post_meta($post->ID, '_gallery_type', TRUE); if (!$gallery_type) $gallery_type = 'attachment'; ?> <input type="hidden" name="gallery_type_noncename" id="gallery_type_noncename" value="<?php echo wp_create_nonce( 'gallery_type'.$post->ID );?>" /> <input type="radio" name="gallery_type" value="any" <?php if ($gallery_type == 'any') echo "checked=1";?>> Any.<br/> <input type="radio" name="gallery_type" value="attachment" <?php if ($gallery_type == 'attachment') echo "checked=1";?>> Only Attachments.<br/> <input type="radio" name="gallery_type" value="post" <?php if ($gallery_type == 'post') echo "checked=1";?>> Only Posts.<br/> <input type="radio" name="gallery_type" value="gallery" <?php if ($gallery_type == 'gallery') echo "checked=1";?>> Only Galleries.<br/> <?php } ?>
Lines 6-7 – Get previously saved gallery type data (if any). If none, then use attachment as the default gallery type.
Line 9 – Add hidden security nonce key.
Lines 10-13 – Render the appropriate radio buttons, and check the one that was previously selected.
This renders a new custom metabox in our Gallery screen –
We can use this method to render any type of HTML form that we want for our custom post type interface.
However, we are not done yet. add_meta_box only adds the input controls; we must still attach and save the user data to our gallery object. This is achieved using the save_post action hook.
// Add to admin_init function add_action('save_post', array(&$this,'save_gallery_data') ); function save_gallery_data($post_id) { // verify this came from the our screen and with proper authorization. if ( !wp_verify_nonce( $_POST['gallery_type_noncename'], 'gallery_type'.$post_id )) { return $post_id; } // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; // Check permissions if ( !current_user_can( 'edit_post', $post_id ) ) return $post_id; // OK, we're authenticated: we need to find and save the data $post = get_post($post_id); if ($post->post_type == 'gallery') { update_post_meta($post_id, '_gallery_type', esc_attr($_POST['gallery_type']) ); return(esc_attr($_POST['gallery_type'])); } return $post_id; }
[This function was adapted from the add_meta_box example in the WordPress Codex]
Lines 6-8 – Verify that the form came from our gallery type metabox, and our gallery custom post type screen.
Lines 11-12 – We don’t need to save the data if it is just an autosave event.
Lines 15-16 – Only save the data if the user has proper permissions to edit the given post object.
Lines 20-24 – Save the gallery type custom metabox data.
We Are Done!
If you want to include specialized metaboxes from plugins or themes, you will need to edit the plugin file and look for the relevant add_meta_box and save_post hooks. Then, just include them in your own admin_init function.
Make sure to use your own custom post type name (argument 4) when issuing the add_metabox command.
mike says
Hi Shiba am a newbie to wordpress, I just installed a plugin with a custom post type, but has no option for discussion and comment. pls Kindly tell me how to include the comment option, to allow users comment and discuss on such page. Thanks a lot in advance.
Doan Tien Tai says
Hi Shiba, thanks for the tut! I’m new to WordPress. I want to ask you a question.
I am using a plugin named Simple Staff List to create Staff Pages for all the staff. I want each of them be able to edit their page. However, the plugin doesn’t have Author Metabox in Editing page.
So I tried to add the ‘author’ in the ‘support’ from this:
‘supports’ => array(‘title’,’thumbnail’,’excerpt’)
To be this:
‘supports’ => array( ‘title’, ‘thumbnail’, ‘author’, ‘excerpt’ )
I come back to the editing page, and it appears. Then I change the author value to another user (user type: Author) However, when I login using that user account, I still cannot edit the post. I guess I should change something more, what else I should do?
Ben says
My god. A radio button set that actually saving & actually appears ‘checked’ after I hit save! I cant believe my eyes!! LOL
You have no idea how many tutorials I’ve gone through but still cant get that friggin radio checked. Not even the mentioned-everywhere, so-called ‘Meta Box Framework’ that kind of too much for what it is, i think. I got so lost into it when all I want to do is to get a set of radio buttons. Kind of agree with Justin Tadlock whom i remember wrote that there are just too many tutorials about this and mostly making the thing a lot more complicated while actually it is not.
I think your kind of post is what most of us need. Simple but the correct wordpress codex way, and mere-mortals readable.
Finally I could sleep. Thanks again for your work posting this 🙂
Chris says
hello there,
first of thank you for your great plugin i’m using shiba Mlib and it works a treat. I am currently looking at a way to set the page attributes metabox on the gallery post page so i can assign different templates to different galleries.
Could you please point me in the right direction, i have purchased the hermes theme from themeforest but the DEV hasn’t been able to help me.
kind regards
Chris
Vince Kurzawa says
In your last screenshot I noticed your “Excerpt” box has been renamed to “Gallery Description.” I’ve been looking all over Google and can’t find a way to do this.
Would you let me know, or point me in the right direction of how to do this?
ShibaShake says
That is actually a custom metabox that I added with –
add_meta_box( ‘post-content-div’, __(‘Gallery Description’), ‘gallery_description_metabox’, ‘gallery’, ‘normal’, ‘high’);
Vince Kurzawa says
Oh cool. Thanks for the code snippet, it helps a bunch. There is just so much to learn about the WordPress API!
Blankforte says
Ups! Sorry, delete my earlier post. Forgot to write my question.
Cant get the code to work, have tried everything. Can you se whats wrong?
ShibaShake says
Your posted code didn’t come through properly. Try encapsulating your code in <pre> tags, or use pastebin.