Shiba

Adventures in WordPress

  • Home
  • Dog
  • Art
  • Contact
  • WordPress Articles
    • WP Plugins
    • WP Programming
    • WP Admin Panels
    • WP Theme Design
    • WP How-To
    • WP Theme Images
You are here: Home / WordPress Admin / Custom Post Type / Add a Metabox to Your Custom Post Type Screen

Add a Metabox to Your Custom Post Type Screen

by ShibaShake 27 Comments

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.

Gallery custom post type screen with built in title, thumbnail, and excerpt, metaboxes.
Gallery custom post type screen with built in title, thumbnail, and excerpt, metaboxes.

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.

Custom post type tag and category metabox.
Custom post type tag and category metabox.

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

Custom meta-box with a set of radio-buttons.
Custom meta-box with a set of radio-buttons.

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 –

New gallery type metabox added to our gallery custom post type interface.
New gallery type metabox added to our gallery custom post type interface.

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.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Comments

1 2 Next »
  1. jamie says

    February 2, 2011 at 5:37 pm

    this would have been a great tut had you not left out the part about retrieving the information from the database. How do I get the values from the radio buttons?

    Reply
    • ShibaShake says

      February 3, 2011 at 2:58 pm

      I am not sure I understand your question.

      In the save_gallery_data function, values from the radio buttons ($_POST[‘gallery_type’]) are retrieved and stored (line 22).

      Reply
  2. Erik says

    January 30, 2011 at 4:50 am

    I’ve made a blank example for custom meta boxes on posts, and give explanation on how to insert them into custom post types as well here. I’d love to know what you think.

    Reply
    • ShibaShake says

      February 3, 2011 at 2:40 pm

      Good tutorial, I like it!

      Reply
  3. sebouille says

    October 25, 2010 at 1:22 am

    Hi
    How i can restrict meta box category with arg child-of ?

    I created a plugin with
    add_action(‘load-post.php’, array(‘Myplugin’,’loadpost’));
    And
    function loadpost() {
    remove_meta_box(‘categorydiv’, ‘post’, ‘normal’);
    add_meta_box(‘categorydiv’, _(‘Category’), ‘post_categories_meta_box’, ‘post’, ‘side’, ‘core’, array( ‘taxonomy’ => ‘category’, ‘child_of’ => 80));
    }
    Have any idea ?
    Thanks for great blog

    Reply
    • sebouille says

      October 26, 2010 at 4:10 am

      I find with this function
      wp_terms_checklist($post->ID, array( ‘taxonomy’ => $taxonomy, ‘descendants_and_self’ => $wp_cat_id_mother, ‘selected_cats’ => $idCatSelected ) )
      So
      1) remove_meta_box(‘categorydiv’, ‘post’, ‘normal’);
      2) add_meta_box(‘categorydiv1’, _(‘Categories’), array( ‘MyPluginClass’, ‘display_restrict_category’), ‘post’, ‘side’, ‘core’);
      3)
      function display_restrict_category( ) {
      …
      wp_terms_checklist($post->ID, array( ‘taxonomy’ => $taxonomy, ‘descendants_and_self’ => $wp_cat_id_mother, ‘selected_cats’ => $idCatSelected ) )
      …
      }

      Thanks

      Reply
  4. Frank Perez says

    August 27, 2010 at 10:06 pm

    Here’s a good plugin that handles all the custom metaboxes for you as well as custom post types. http://wordpress.org/extend/plugins/custom-metaboxes/

    Reply
  5. Alex says

    July 6, 2010 at 4:33 pm

    SOLVED IT !!!

    Its necesary to add this action

    add_action(‘admin_menu’, ‘architecture_admin_menu’);

    Reply
    • Jacob says

      July 13, 2010 at 9:11 am

      Where do you add the action? beginning or end of the code?

      Would be great to see the code in full!

      -J

      Reply
      • ShibaShake says

        July 13, 2010 at 9:16 pm

        I usually add the admin_menu hook at the beginning of my theme functions.php file or at the beginning of my main plugin file. I put it together with the init and admin_init hooks. When I use class wrappers, I put it within the class constructor function. If you want to look at an example plugin with these function calls then check out the Shiba Example plugin.

        The register_post_type function call I execute from my init function.

        Both the Shiba Media Library plugin and Shiba Custom Background plugin use custom post type metaboxes. Full working code can be found there but the plugins also contain a whole bunch of other stuff.

  6. Alex says

    July 6, 2010 at 4:14 pm

    Ey men! your last posts about custom post types are amazing!! I just created my first custom type, but when trying to add a meta box gives me this error.

    Fatal error: Call to undefined function add_meta_box() in /home/xxx/public_html/wp-content/themes/xxx/custom-types.php on line 43

    custom-types is an include in functions.php

    I am using wordpress 3.0

    This is the code in custom-types.php

    	$labels = array(
    		'name' => _x('Architecture', 'post type general name'),
    		'singular_name' => _x('Architecture', 'post type singular name'),
    		'add_new' => _x('Add New', 'work'),
    		'add_new_item' => __("Add New work"),
    		'edit_item' => __("Edit work"),
    		'new_item' => __("New work"),
    		'view_item' => __("View work"),
    		'search_items' => __("Search Works"),
    		'not_found' =>  __('No work found'),
    		'not_found_in_trash' => __('No work 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','editor')
    	  ); 
    	  register_post_type('architecture',$args);
    	  
    	  function architecture_type_metabox($post) {
    		
    	}
    	
    	add_meta_box('architecture-type-div', __('Datos tecnicos'),  'architecture_type_metabox', 'architecture', 'normal', 'low');
    

    Please! help, wp is correctly updated to 3.0, i can find the function add_meta_box and cant find why this happens!

    ++Thanks++

    Reply
    • Andrew says

      September 9, 2011 at 8:13 am

      FYI, this part is not “out of the box” so you have to wrap it into a function and use add_action such as


      add_action( 'admin_init', 'news_meta_boxes', 1 );

      // Add meta box goes into our admin_init function
      function news_meta_boxes() {
      add_meta_box('gallery-type-div', __('Gallery Type'), 'gallery_type_metabox', 'news', 'normal', 'high');
      }

      This also lets you add all your meta boxes in one add_action as referenced in the codex at http://codex.wordpress.org/Function_Reference/add_meta_box

      Reply
  7. Ben Palmer says

    June 29, 2010 at 3:17 am

    Thanks very much, i’ve been searching for how to do meta box stuff on the new custom post types and this article has finally helped me to understand.

    Reply
  8. Darren says

    June 28, 2010 at 10:08 am

    Thanks for this, very useful!

    I created a checkbox to flag featured “Best Practices” on a site I am putting together. Perhaps this will be helpful to your readers:

    add_action('admin_menu', 'featured_add_custom_box');
    add_action('save_post', 'featured_save_postdata');
    
    /* Adds a custom section to the "advanced" Best Practices */
    function featured_add_custom_box() {
    	add_meta_box( 'featured_sectionid', __( 'Featured', 'featured_textdomain' ), 'featured_inner_custom_box', 'bestpractices', 'advanced' );
    }
       
    /* Prints the inner fields for the custom post/page section */
    function featured_inner_custom_box( $post ) {
    	
    	$featured = get_post_meta($post->ID, '_featured', true);
    	if ($featured == 1) $checked = 'checked="checked"'; else $checked = '';
    	
      echo 'ID) . '" />';
      echo '' . __("Featured?", 'featured_textdomain' ) . ' ';
      echo '';
    }
    
    /* When the post is saved, saves our custom data */
    function featured_save_postdata( $post_id ) {
    
    	if ( !wp_verify_nonce( $_POST['featured_noncename'], 'featured'.$post_id ))
    		return $post_id;
    
      if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
        return $post_id;
    
      if ( !current_user_can( 'edit_page', $post_id ) )
        return $post_id;
    
    	$post = get_post($post_id);
    	if ($post->post_type == 'bestpractices') {
    		if(esc_attr($_POST['featured'] == "on")) $val = 1; else $val = 0;
    		update_post_meta($post_id, '_featured', $val );
    		return(esc_attr($_POST['featured']));
    	}
    }
    
    Reply
    • ShibaShake says

      June 28, 2010 at 2:27 pm

      Examples like these are always very useful. Thanks for sharing it with us Darren.

      Reply
  9. Matt says

    June 21, 2010 at 7:11 pm

    Oh, my gosh, thank you thank you thank you. I have been dealing with this stupid nonce thing looking for help. I stumbled onto your site and this method works great. Thank you so much!

    Reply
1 2 Next »

Recent Posts

  • Screenshot of an example article in code view of a modified Gutenberg editor.How to Harness the Power of WordPress Gutenberg Blocks and Combine It with Legacy Free-Form Text
  • Screenshot of the Success, WordPress has been installed page.Migrating Your WordPress Website to Amazon EC2 (AWS)
  • Screenshot of WinSCP for creating a SFTP configuration.How to Set-Up SFTP on Amazon EC2 (AWS)
  • WordPress Gutenberg code view screenshot of this article.How to Prevent Gutenberg Autop from Messing Up Your Code, Shortcodes, and Scripts
  • Screenshot of the Success, WordPress has been installed page.How to Create a WordPress Website on Amazon EC2 (AWS)

Recent Comments

  • Create Pop-up Windows in Your WordPress Blog with Thickbox (57)
    • Jim Camomile
      - I have used this tutorial several times and it is one of the few simple and effective ways to add popups with dynamic content, ...
  • How to Add Admin Columns in WordPress (7)
    • Andy Globe
      - Hi Friends, I am facing two problem in WordPress admin1. Load custom CSS for wp-admin on user-role base (editor) 2. ...
  • Example blog front-page using excerpts and the Shiba Theme.Optimize Your WordPress Plugins with Tags (5)
    • DF
      - thanks, i went the other way and added a filter if pages I wanted.
  • WordPress Search Widget – How to Style It (57)
    • Nelson
      - Tanks master - Fine
  • Update custom inputs with the proper data using Javascript.Expand the WordPress Quick Edit Menu (59)
    • Mike G
      - This is exactly what is happening to me. It is updating the value in the database and in the column, but I have to refresh ...

Copyright © 2022 · Genesis Skins by ShibaShake · Terms of Service · Privacy Policy ·