Meta Boxes
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:

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.
commentstatusdiv
– Discussion,slugdiv
– Slug,commentsdiv
– Comments,postexcerpt
– Excerpt,authordiv
– Author,revisionsdiv
– Revisions,postcustom
– Custom Fields,trackbacksdiv
– Send Trackbacks,categorydiv
– Categories,tagsdiv-post_tag
– Tags,{Taxonomy name}div
– Any taxonomy,submitdiv
– Publish.
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:
thumbnail
— Featured Image metaboxauthor
— Author metaboxexcerpt
— Excerpt metaboxtrackbacks
— Send trackbacks metaboxcustom-fields
— Custom Fields metaboxcomments
— Comments metaboxrevisions
— Revisions metaboxpage-attributes
— Page Attributes metabox
You can also remove such areas as title or content editor:
title
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:

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.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:

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:
- Install and activate my plugin,
- 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! ⚡️

Comments — 9
Like your tut! I get this 'Notice: Undefined variable: html in C:\xampp\htdocs\sites\test-wordpress\wp-content\themes\wordpress-test\functions.php on line 879'.
If I use
instead of
the Notice goes away. Thanks, Jamie
Thank you. I’ve fixed it in my code.
What PHP version? 5 or 7.? For me is everything ok. I have version PHP 7.3 on the server.
I have a WordPress site and this article is very helpful. Great example code and very easy to understand. Really is very nice.
Thanks,
That’s a nice post. Can you tell me how to remove custom meta-box? I have a plugin where I’ve created a custom meta-box. Now I want to remove it on button click. I’ve created that custom meta-box in main plugin while, whereas I want to delete it via another settings file. Thanks!
Just check the options with
get_option()
and if the metabox is turned off, do not add it.So finally something that actually works. But I am having difficult times figuring out how to display the content of text field.
Also not sure if check box actually blocks robots for real or it is just for demonstration purposes?
So I use two languages on my website and I need a meta box to manually add language: lang=”en”. I want echo this in my html head. Would you be able to help me with this one?
I tried and but with no results.
Appreciate any help.
Hi Sebastian,
Yes, it is just for demonstration purposes here.
I recommend to use a select dropdown field for languages:
Thank you, very helpful tutorial :)
Comments are closed.