Explanation
Register Meta Box:
- The
add_meta_box
function is used to create a new meta box. - The
display_custom_meta_box
function is called to display the meta box content. It retrieves the current value of the custom field and displays it in a text input field.
Save Meta Box Data:
- The
save_custom_meta_box_data
function saves the custom field data when the post is saved. - It includes several checks for security, including a nonce check, user permissions, and ensuring the data is sanitized.
Nonce Field:
- A nonce field is added to the meta box form for security. This helps verify that the form request came from the current site and not from a malicious source.
This setup will add a custom text field for a URL to the post edit screen in the WordPress admin. The URL can be saved and retrieved as post meta data.
============== METHOD : 2 ==================
add_meta_box function is used to create custom meta boxes. This function is only responsible for registering and displaying custom meta boxes.
Here is the code to add a custom meta box to WordPress posts:
function custom_meta_box_markup()
{
}
function add_custom_meta_box()
{
add_meta_box("demo-meta-box", "Custom Meta Box", "custom_meta_box_markup", "post", "side", "high", null);
}
add_action("add_meta_boxes", "add_custom_meta_box");
add_meta_box
should be called inside add_meta_boxes
hook.
add_meta_box
takes 7 arguments. Here are the list of arguments:
- $id: Every meta box is identified by WordPress uniquely using its id. Provide an id and remember to prefix it to prevent overriding.
- $title: Title of the meta box on the admin interface.
- $callback:
add_meta_box
calls the callback to display the contents of the custom meta box. - $screen: Its used to instruct WordPress in which screen to display the meta box. Possible values are
"post"
, "page"
, "dashboard"
, "link"
, "attachment"
or "custom_post_type"
id. In the above example we are adding the custom meta box to WordPress posts screen. - $context: Its used to provide the position of the custom meta on the display screen. Possible values are
"normal"
, "advanced"
and "side"
. In the above example we positioned the meta box on side. - $priority: Its used to provide the position of the box in the provided context. Possible values are
"high"
, "core"
, "default"
, and "low"
. In the above example we positioned the meta box - $callback_args: Its used to provide arguments to the callback function.
Here is how the meta box looks:

Here, the custom meta box content is empty because we haven’t yet populated the content.
For demonstration purpose I will add a text input, drop down and a checkbox form field to the custom meta box.
Here is the code:
function custom_meta_box_markup($object)
{
wp_nonce_field(basename(__FILE__), "meta-box-nonce");
?>
<div>
<label for="meta-box-text">Text</label>
<input name="meta-box-text" type="text" value="<?php echo get_post_meta($object->ID, "meta-box-text", true); ?>">
<br>
<label for="meta-box-dropdown">Dropdown</label>
<select name="meta-box-dropdown">
<?php
$option_values = array(1, 2, 3);
foreach($option_values as $key => $value)
{
if($value == get_post_meta($object->ID, "meta-box-dropdown", true))
{
?>
<option selected><?php echo $value; ?></option>
<?php
}
else
{
?>
<option><?php echo $value; ?></option>
<?php
}
}
?>
</select>
<br>
<label for="meta-box-checkbox">Check Box</label>
<?php
$checkbox_value = get_post_meta($object->ID, "meta-box-checkbox", true);
if($checkbox_value == "")
{
?>
<input name="meta-box-checkbox" type="checkbox" value="true">
<?php
}
else if($checkbox_value == "true")
{
?>
<input name="meta-box-checkbox" type="checkbox" value="true" checked>
<?php
}
?>
</div>
<?php
}
Here is how the code works:
- First we set the nonce field so that we can prevent CSRF attack when the form is submitted.
- get_post_meta is used to retrieve meta data from the database. If no such meta data is present, it returns an empty string. If your user has already submitted the form earlier, then we use the meta data stored in database. Otherwise, we switch to the default value.
Here is how the meta box looks now:

Now we need to store the custom meta data when a user submits the form; need to save the post. Here is the code to save meta data when a user clicks on the ‘save draft’ or ‘publish’ button:
function save_custom_meta_box($post_id, $post, $update)
{
if (!isset($_POST["meta-box-nonce"]) || !wp_verify_nonce($_POST["meta-box-nonce"], basename(__FILE__)))
return $post_id;
if(!current_user_can("edit_post", $post_id))
return $post_id;
if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE)
return $post_id;
$slug = "post";
if($slug != $post->post_type)
return $post_id;
$meta_box_text_value = "";
$meta_box_dropdown_value = "";
$meta_box_checkbox_value = "";
if(isset($_POST["meta-box-text"]))
{
$meta_box_text_value = $_POST["meta-box-text"];
}
update_post_meta($post_id, "meta-box-text", $meta_box_text_value);
if(isset($_POST["meta-box-dropdown"]))
{
$meta_box_dropdown_value = $_POST["meta-box-dropdown"];
}
update_post_meta($post_id, "meta-box-dropdown", $meta_box_dropdown_value);
if(isset($_POST["meta-box-checkbox"]))
{
$meta_box_checkbox_value = $_POST["meta-box-checkbox"];
}
update_post_meta($post_id, "meta-box-checkbox", $meta_box_checkbox_value);
}
add_action("save_post", "save_custom_meta_box", 10, 3);
Here is how the code works:
– save_post
hook’s callback is triggered when a post, page and custom post type is saved. We attached a callback to save meta data.
– We verify the nonce. If the nonce is not present or invalid then we don’t save the return the callback.
– We check whether the current logged in admin user has permission to save meta data for that post type. If the user doesn’t have permission, then we return the callback.
– We check if the post is being auto saved. If the save is auto saved, then we return the callback.
– Final check is whether the post type is the same as the meta box post type. If not, then we return the callback.
– We retrieve the values of the form fields using PHP $_POST
variable and save them in database using update_post_meta. update_post_meta
create a new meta data key/value in the database if the key is not present, otherwise it updates the key value.
We can remove custom meta boxes and the default WordPress core meta boxes using remove_meta_box. To remove a meta box you need its ID, screen and content.
Here are the IDs of some important default meta boxes:
- ‘authordiv’ – Author metabox
- ‘categorydiv’ – Categories metabox
- ‘commentstatusdiv’ – Comments status metabox (discussion)
- ‘commentsdiv’ – Comments metabox
- ‘formatdiv’ – Formats metabox
- ‘pageparentdiv’ – Attributes metabox
- ‘postcustom’ – Custom fields metabox
- ‘postexcerpt’ – Excerpt metabox
- ‘postimagediv’ – Featured image metabox
- ‘revisionsdiv’ – Revisions metabox
- ‘slugdiv’ – Slug metabox
- ‘submitdiv’ – Date, status, and update/save metabox
- ‘tagsdiv-post_tag’ – Tags metabox
- ‘{$tax-name}div’ – Hierarchical custom taxonomies metabox
- ‘trackbacksdiv’ – Trackbacks metabox
Here is the code to remove custom fields meta box:
function remove_custom_field_meta_box()
{
remove_meta_box("postcustom", "post", "normal");
}
add_action("do_meta_boxes", "remove_custom_field_meta_box");
Here we triggered remove_meta_box
in do_meta_boxes
hook. But you cannot always call remove_meta_box
inside it. For example, to remove dashboard widgets you need to call it inside wp_dashboard_setup
hook.