add_meta_box()
Adds additional blocks (meta box) on the edit/create post, page, or custom post type screens in the admin panel.
It needs to be called on the hook add_meta_boxes or later.
Use wp_add_dashboard_widget() to add a meta box on the admin panel "Dashboard", "Multisite Dashboard".
All registered data is located in the global array $wp_meta_boxes
, which contains a multidimensional array of all registered meta boxes. It contains their IDs, parameters (args), callback functions (callback), and titles of all post types, including custom ones.
Gutenberg
Disabling the Gutenberg editor via meta box
If the meta box does not work with Gutenberg, and updating it to work with it is not possible, then the Gutenberg editor can be disabled via the meta box.
To do this, you need to pass the argument __block_editor_compatible_meta_box = false
in the $callback_args parameter (parameters passed to the callback function). After this, WordPress will revert to the classic editor with the familiar meta box:
add_meta_box( 'my-meta-box', 'My Meta Box', 'my_meta_box_callback', null, 'normal', 'high', [ '__block_editor_compatible_meta_box' => false, ] );
Support for the Gutenberg editor
When the meta box fully supports the Gutenberg block editor, you can disable the output of the classic meta field block by adding the argument __back_compat_meta_box = false
. Now, when Gutenberg is used, this meta box will no longer be displayed in the meta box area, as it now exists only for backward compatibility. However, it will still be displayed in the Classic editor if Gutenberg is disabled.
add_meta_box( 'my-meta-box', 'My Meta Box', 'my_meta_box_callback', null, 'normal', 'high', [ '__back_compat_meta_box' => false, ] );
No Hooks.
Returns
null
. Returns nothing.
Usage
add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args );
- $id(string) (required)
- id attribute of the HTML tag, container of the block.
- $title(string) (required)
- Title/name of the block. Visible to users.
- $callback(string) (required)
The function that outputs the HTML content of the block. Must output the result to the screen.
Gets the post object as the first parameter.
- $screen(string/array/WP_Screen)
The name of the screen for which the block is added. See get_current_screen(). For example, it can be:
- For post types:
post
,page
,link
,attachment
orcustom_post_type
- Or for other admin pages:
link
,comment
. - You can specify multiple types in an array:
array('post', 'page')
. Since version 4.4.
Default: null (current screen)
- For post types:
- $context(string)
The place where the block should be shown:
normal
,advanced
orside
.Also, you can specify a custom value; in this case, the output of the meta box (context handling) will need to be hooked to the appropriate hook. See example 6.
Default: 'advanced'- $priority(string)
- The priority of the block for display above or below other blocks:
high
orlow
. You can also specifycore
,default
.
Default: 'default' - $callback_args(array)
Arguments to pass to the callback function specified in the $callback parameter. The callback function will receive the post data (object $post) and the arguments passed in this parameter.
Default: null
Examples
More examples see in the questions.
#1 Display the metabox in an custom place
This example shows how to output the metabox in an custom place: right after the header field. To do this, set your own value for the $context parameter, and then output it with the edit_form_after_title hook. You can see the whole map of hooks on the post editing page here.
add_meta_box( 'my-meta-box', 'My Meta Box', 'my_meta_box_callback', null, 'my_custom_context', 'high' ); add_action( 'edit_form_after_title', 'show_custom_meatbox' ); function show_custom_meatbox( $post ) { do_meta_boxes( null, 'my_custom_context', $post ); }
#2 New accordion tab (metabox in the accordion menu)
This example shows how to add an additional accordion element to the WordPress menu settings page.
<?php add_action( 'admin_head-nav-menus.php', 'register_my_meta_box_accordion_nav_menus' ); function register_my_meta_box_accordion_nav_menus() { add_meta_box( 'my-custom-meta-box', 'My metabox', 'render_my_meta_box_accordion_nav_menus', 'nav-menus', 'side' ); } function render_my_meta_box_accordion_nav_menus() { ?> <div class="my-custom-meta-box" id="my-custom-meta-box"> Metabox content </div> <?php }
We get it:

#3 PHP class
This example shows how to add an extra block in OOP-style:
#4 Accordion tab with content
Finished code that adds a new item to the navigation menu (in the accordion) and fills it, allowing you to select a media library item (files) and add it into the menu:
We get it:

Note: The base of code is taken from the file [custom-menu-panel.php] (https://gist.github.com/nikolov-tmw/8698598), found on github, which implements adding custom objects to the list.
#5 Using the $callback_args parameter
The first parameter passes post data (array $_POST).
The second has an array of $callback_args arguments.
// This function adds a Block that passes additional parameters to the // `callback` my_metabox_callback() function. function add_my_meta_box() { $var1 = "this"; $var2 = "that"; $callback_args = array( 'foo'=>$var1,'bar'=>$var2 ); add_meta_box( 'metabox_id', 'Metabox Title', 'my_metabox_callback', 'page', 'normal', 'low', $callback_args ); } // $post is an object containing data from the global array $_POST // $metabox is an array of metabox_id, title, callback // and the new passed arguments in the $callback_args parameter function my_metabox_callback( $post, $metabox ){ echo 'Last Modified: ' . $post->post_modified; // the time the post was last modified echo $metabox['args']['foo']; // once echo $metabox['args']['bar']; // two echo get_post_meta( $post->ID, 'my_custom_field', true ); // arbitrary field value }
#6 Using the anonymous function
You can pass an anonymous function as a callback function to the $callback_args parameter, for example:
add_action( 'add_meta_boxes', 'add_custom_meatbox' ); function add_custom_meatbox(){ $screens = array( 'post', 'page' ); add_meta_box( 'wpsb', __( 'Metabox title', 'my-plugin' ), function() { _e( 'Metabox content', 'my-plugin' ); }, $screens ); }
It's a little more convenient if you just need to get something out in the metabox.
#7 Metabox for posts and pages
An example of adding a custom block to the edit/create pages of posts and static pages:
// Add blocks to the main column on the post/page pages add_action( 'add_meta_boxes', 'myplugin_add_custom_box' ); // Saving data when the post is saved add_action( 'save_post', 'myplugin_save_postdata' ); function myplugin_add_custom_box(){ $screens = array( 'post', 'page' ); add_meta_box( 'myplugin_sectionid', 'Meta block name', 'myplugin_meta_box_callback', $screens ); } // HTML code of the block function myplugin_meta_box_callback( $post, $meta ){ $screens = $meta['args']; // Use nonce for verification wp_nonce_field( plugin_basename(__FILE__), 'myplugin_noncename' ); // field value $value = get_post_meta( $post->ID, 'my_meta_key', 1 ); // Form fields for entering data echo '<label for="myplugin_new_field">' . __("Description for this field", 'myplugin_textdomain' ) . '</label> '; echo '<input type="text" id="myplugin_new_field" name="myplugin_new_field" value="'. $value .'" size="25" />'; } function myplugin_save_postdata( $post_id ) { // make sure the field is set. if ( ! isset( $_POST['myplugin_new_field'] ) ) return; // check the nonce of our page, because save_post can be called from another location. if ( ! wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) ) return; // if this is autosave do nothing if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return; // check user permission if( ! current_user_can( 'edit_post', $post_id ) ) return; // Everything is OK. Now, we need to find and save the data // clear the value of the input field. $my_data = sanitize_text_field( $_POST['myplugin_new_field'] ); // Update data in the database. update_post_meta( $post_id, 'my_meta_key', $my_data ); }
Notes
- Global. Array. $wp_meta_boxes Global meta box state.
Changelog
Since 2.5.0 | Introduced. |
Since 4.4.0 | The $screen parameter now accepts an array of screen IDs. |