Meta Boxes

  1. Remove meta boxes
  2. Add a meta box

In the first part of this tutorial I will show you how to remove WordPress default meta boxes, in the second part we create a custom meta box with multiple fields from scratch. Like this:

WordPress meta box for Pages custom post type with multiple fields
A simple meta box with multiple fields for “Pages” post type.

Remove Default Meta Boxes

On every edit post type page WordPress already has predefined meta boxes, you can even see a couple of them on the screenshot above, I mean “Page attributes” and “Featured image” of course.

There are two ways to remove a default metabox – using remove_meta_box() function or with the help of remove_post_type_support().

remove_meta_box()

Straight to the example. Let’s suppose that we have to remove both metaboxes I’ve already mentioned – “Page attributes” and “Featured image”. The code will be:

add_action( 'admin_menu', 'misha_remove_meta_box' );
 
function misha_remove_meta_box(){
	// Featured image
	remove_meta_box( 'postimagediv', 'page', 'normal' );
	// Page attributes
	remove_meta_box( 'pageparentdiv', 'page', 'normal' );
}

The first parameter of the function is a meta box ID, the easiest way to find out it is to inspect the code in your browser, but just in a case here is the list of default meta boxes IDs.

The second parameter of remove_meta_box() function is a post type you would like to remove it from.

remove_post_type_support()

Let’s try to do the same we did with remove_meta_box() function right now.

add_action( 'init', 'misha_remove_meta_box_2' );
 
function misha_remove_meta_box_2() {
	// Featured image
	remove_post_type_support( 'page', 'thumbnail' );
	// Page attributes
	remove_post_type_support( 'page', 'page-attributes' );
}

As you can see the code is similar, but at the same time is different. I think the most correct way to remove default WordPress meta boxes is with remove_post_type_support() function, because it actually turns off a specific feature for a specific post type, and remove_meta_box() function just removes a meta box.

Features / Meta Boxes:

You can also remove such areas as title or content editor:

Add Custom Meta Box

Finally we came to the part of the tutorial where I am going to show you how to create a meta box in WordPress, here is a screenshot, just to remind you:

WordPress meta box for Pages custom post type with multiple fields
A simple meta box with multiple fields for “Pages” post type.

There are 2 ways of doing it – fully from scratch or with the help of my meta boxes plugin.

Step 1. add_meta_box()

Let’s begin with add_meta_box() function inside admin_menu action hook, but add_meta_boxes action hook is also ok.

add_action( 'admin_menu', 'misha_add_metabox' );
 
function misha_add_metabox() {
 
	add_meta_box(
		'misha_metabox', // metabox ID
		'Meta Box', // title
		'misha_metabox_callback', // callback function
		'page', // post type or post types in array
		'normal', // position (normal, side, advanced)
		'default' // priority (default, low, high, core)
	);
 
}
 
function misha_metabox_callback( $post ) {
 
	echo 'hey';
 
}

Once you insert this code to functions.php of your child theme or in a custom plugin, this meta box should appear:

add_meta_box function example
Simple example of using add_meta_box() function.

As you can see all we printed inside the callback function is now displayed inside the meta box.

Let’s dive into it and fill our metabox with fields.

Step 2. Callback function with meta box HTML

In the code below I populated our meta box with multiple fields.

function misha_metabox_callback( $post ) {
 
	$seo_title = get_post_meta( $post->ID, 'seo_title', true );
	$seo_robots = get_post_meta( $post->ID, 'seo_robots', true );
 
	// nonce, actually I think it is not necessary here
	wp_nonce_field( 'somerandomstr', '_mishanonce' );
 
	echo '<table class="form-table">
		<tbody>
			<tr>
				<th><label for="seo_title">SEO title</label></th>
				<td><input type="text" id="seo_title" name="seo_title" value="' . esc_attr( $seo_title ) . '" class="regular-text"></td>
			</tr>
			<tr>
				<th><label for="seo_tobots">SEO robots</label></th>
				<td>
					<select id="seo_robots" name="seo_robots">
						<option value="">Select...</option>
						<option value="index,follow"' . selected( 'index,follow', $seo_robots, false ) . '>Show for search engines</option>
						<option value="noindex,nofollow"' . selected( 'noindex,nofollow', $seo_robots, false ) . '>Hide for search engines</option>
					</select>
				</td>
			</tr>
		</tbody>
	</table>';
 
}

Our meta box:

WordPress meta box with multiple fields
Now we’ve printed multiple fields in the callback function.

Step 3. Save meta box data

If you are using this metabox on the page edit screen or for a custom post type, don’t forget to redefine supported post types on line 23, otherwise metabox data won’t be saved.

Functions update_post_meta() and delete_post_meta() (lines 27-36) should be called for each input field in your meta box.

add_action( 'save_post', 'misha_save_meta', 10, 2 );
 
function misha_save_meta( $post_id, $post ) {
 
	// nonce check
	if ( ! isset( $_POST[ '_mishanonce' ] ) || ! wp_verify_nonce( $_POST[ '_mishanonce' ], 'somerandomstr' ) ) {
		return $post_id;
	}
 
	// check current use permissions
	$post_type = get_post_type_object( $post->post_type );
 
	if ( ! current_user_can( $post_type->cap->edit_post, $post_id ) ) {
		return $post_id;
	}
 
	// Do not save the data if autosave
	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
		return $post_id;
	}
 
	// define your own post type here
	if( $post->post_type != 'page' ) {
		return $post_id;
	}
 
	if( isset( $_POST[ 'seo_title' ] ) ) {
		update_post_meta( $post_id, 'seo_title', sanitize_text_field( $_POST[ 'seo_title' ] ) );
	} else {
		delete_post_meta( $post_id, 'seo_title' );
	}
	if( isset( $_POST[ 'seo_robots' ] ) ) {
		update_post_meta( $post_id, 'seo_robots', sanitize_text_field( $_POST[ 'seo_robots' ] ) );
	} else {
		delete_post_meta( $post_id, 'seo_robots' );
	}
 
	return $post_id;
 
}

Please keep in mind, that depending on your field type you must use sanitization, so in the above example I am using sanitize_text_field() function, but there are also another ones, like sanitize_textarea() for textarea fields, sanitize_email() etc.

Create the same Meta Box, the Easy Way

Above was a lot of code. And it is only for 2 input fields. What happens if your metabox should have let’s say 20 fields?

That’s why I never create meta boxes from scratch, I created a plugin for myself, which saves me so much time, you can download it here.

As simple as that:

  1. Install and activate my plugin,
  2. Paste the code below into your current theme functions.php:
add_filter( 'simple_register_metaboxes', 'misha_create_a_metabox' );
 
function misha_create_a_metabox( $metaboxes ) {
 
	$metaboxes[] = array(
 		'id'	=> 'my_metabox',
 		'name'	=> 'Meta Box',
 		'post_type' => array( 'page' ),
 		'fields' => array(
			array(
				'id' => 'seo_title',
				'label' => 'SEO title',
				'type' => 'text'
			),
			array(
				'id' => 'seo_robots',
				'label' => 'SEO robots',
				'type' => 'select'
				'placeholder' => 'Select...',
				'options' => array(
					'index,follow' => 'Show for search engines',
					'noindex,nofollow' => 'Hide for search engines',
				),
			)
 		)
 	);
 
	return $metaboxes;
 
}

And we have the same meta box! ⚡️

WordPress meta box with multiple fields
The same meta box with multiple fields created with my plugin.

Some related stuff

Misha Rudrastyh

Misha Rudrastyh

I love WordPress, WooCommerce and Gutenberg so much. 11 yrs of experience.

Need some custom developer help? Get in touch