How to Add Metaboxes to WordPress Custom Post Types

Posted OnFeb 3, 2014     CategoryDevelopment     CommentsNo comment

In this tutorial we’re going to demonstrate how to add metaboxes to custom post types so you can store helpful metadata where required.

We’re following on from our previous tutorials, how to create a custom post type and how to add taxonomies to a custom post type, and just like those, you’ll need access to your WordPress server to make changes to Theme files.

Step 1) Connect to your server and open functions.php

Step 2) We need to register the Metabox. Start off the add_action with the following arguments:

add_action( 'add_meta_boxes', 'recipe_details_box' );

This tells WordPress we want to add a meta box and the function to call for the required data will be recipe_details_box, so as you might expect, we now need to create that function.

function recipe_details_box() {
	add_meta_box( 
		'recipe_details_box',
		__( 'recipe Details', 'myplugin_textdomain' ),
		'recipe_details_box_content',
		'recipe',
		'normal',
		'high'
	);

}

The main part to note here is ‘normal’ – this means that the metabox will appear under the post editor, if you define ‘side’ instead, it’ll appear on in the right hand column.

Step 3) Now it’s time to define what we want in the metabox, in the form of inputs. Start by creating a function called recipe_details_box_content, which you probably noticed we put as an argument just above when registering the metabox.

function recipe_details_box_content( $post ) {

	wp_nonce_field( plugin_basename( __FILE__ ), 'recipe_details_box_content_nonce' );
	echo '<label for="recipe_details_ingredients">Ingredients: </label>';
	echo '<input type="text" id="recipe_details_ingredients" name="recipe_details_ingredients" placeholder="enter ingredients">';
	echo '<p>--- OR ---</p>';
	echo '<label for="recipe_details_time">Time: </label>';
	echo '<input type="text" id="recipe_details_time" name="recipe_details_time" placeholder="HH:MM:SS">';

}

The bulk of what you see here is just defining the input form, and because we’re writing in PHP, we have to use the echo function to make it appear in the page’s HTML.

Step 4) Finally, we need to add permissions and auto save functionality to the metabox.

We start with add_action, hooking into save_post and providing the function name that does the heavy lifting, in this case, recipe_details_box_save.

add_action( 'save_post', 'recipe_details_box_save' );

Now as you may have guessed, we need to create that function, the explanation will be broken into two parts.

function recipe_details_box_save( $post_id ) {

	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
		return;
	if ( !wp_verify_nonce( $_POST['recipe_details_box_content_nonce'], plugin_basename( __FILE__ ) ) )
		return;  
	if ( 'page' == $_POST['post_type'] ) {
		if ( !current_user_can( 'edit_page', $post_id ) )
			return;

	} else {
	
		if ( !current_user_can( 'edit_post', $post_id ) )
			return;
	 }

We’re just using some very simple if statements, which ultimately allows for autosave and will allow saving if the user viewing the post can edit the post. This means it’s now time to wrap it up.

	$recipe_details_ingredients = $_POST['recipe_details_ingredients'];
	update_post_meta( $post_id, 'recipe_details_ingredients', $recipe_details_ingredients );
	$recipe_details_time = $_POST['recipe_details_time'];
	update_post_meta( $post_id, 'recipe_details_time', $recipe_details_time );
}

What we’re doing here is, when save draft or publish is hit, assigning the metabox information to appropriately named variables, then using the update_post_meta function to write the information to the database.

Step 5) Head into the Dashboard and confirm your changes work. When editing a custom post, you should see something like so.

metabox

Add some information to it, and then hit save draft. When the page reloads, scroll down, and you should see the metabox information in the form of custom fields.

metadata in custom fields

For your review, here’s the code we’ve used in this tutorial in one block.

add_action( 'add_meta_boxes', 'recipe_details_box' );
function recipe_details_box() {
	add_meta_box( 
		'recipe_details_box',
		__( 'recipe Details', 'myplugin_textdomain' ),
		'recipe_details_box_content',
		'recipe',
		'normal',
		'high'
	);

}
//what we want to put in the metabox
function recipe_details_box_content( $post ) {

	wp_nonce_field( plugin_basename( __FILE__ ), 'recipe_details_box_content_nonce' );
	echo '<label for="recipe_details_ingredients">Ingredients: </label>';
	echo '<input type="text" id="recipe_details_ingredients" name="recipe_details_ingredients" placeholder="enter ingredients">';
	echo '<p>--- OR ---</p>';
	echo '<label for="recipe_details_time">Time: </label>';
	echo '<input type="text" id="recipe_details_time" name="recipe_details_time" placeholder="HH:MM:SS">';

}
//permissions for the meta box.
add_action( 'save_post', 'recipe_details_box_save' );

function recipe_details_box_save( $post_id ) {

	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
		return;
	if ( !wp_verify_nonce( $_POST['recipe_details_box_content_nonce'], plugin_basename( __FILE__ ) ) )
		return;  
	if ( 'page' == $_POST['post_type'] ) {
		if ( !current_user_can( 'edit_page', $post_id ) )
			return;

	} else {
	
		if ( !current_user_can( 'edit_post', $post_id ) )
			return;
	 }

	$recipe_details_ingredients = $_POST['recipe_details_ingredients'];
	update_post_meta( $post_id, 'recipe_details_ingredients', $recipe_details_ingredients );
	$recipe_details_time = $_POST['recipe_details_time'];
	update_post_meta( $post_id, 'recipe_details_time', $recipe_details_time );
}

Leave a Reply

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

Send this to friend