Adds a meta box to one or more screens.
Parameters
$id
stringrequired- Meta box ID (used in the
'id'
attribute for the meta box). $title
stringrequired- Title of the meta box.
$callback
callablerequired- Function that fills the box with the desired content.
The function should echo its output. $screen
string|array|WP_Screenoptional- The screen or screens on which to show the box (such as a post type,
'link'
, or'comment'
). Accepts a single screen ID, WP_Screen object, or array of screen IDs. Default is the current screen. If you have used add_menu_page() or add_submenu_page() to create a new screen (and hence screen_id), make sure your menu slug conforms to the limits of sanitize_key() otherwise the'screen'
menu may not correctly render on your page.Default:
null
$context
stringoptional- The context within the screen where the box should display. Available contexts vary from screen to screen. Post edit screen contexts include
'normal'
,'side'
, and'advanced'
. Comments screen contexts include'normal'
and'side'
. Menus meta boxes (accordion sections) all use the'side'
context. Global default is'advanced'
.Default:
'advanced'
$priority
stringoptional- The priority within the context where the box should show.
Accepts'high'
,'core'
,'default'
, or'low'
. Default'default'
.Default:
'default'
$callback_args
arrayoptional- Data that should be set as the $args property of the box array (which is the second parameter passed to your callback).
Default:
null
Source
function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
global $wp_meta_boxes;
if ( empty( $screen ) ) {
$screen = get_current_screen();
} elseif ( is_string( $screen ) ) {
$screen = convert_to_screen( $screen );
} elseif ( is_array( $screen ) ) {
foreach ( $screen as $single_screen ) {
add_meta_box( $id, $title, $callback, $single_screen, $context, $priority, $callback_args );
}
}
if ( ! isset( $screen->id ) ) {
return;
}
$page = $screen->id;
if ( ! isset( $wp_meta_boxes ) ) {
$wp_meta_boxes = array();
}
if ( ! isset( $wp_meta_boxes[ $page ] ) ) {
$wp_meta_boxes[ $page ] = array();
}
if ( ! isset( $wp_meta_boxes[ $page ][ $context ] ) ) {
$wp_meta_boxes[ $page ][ $context ] = array();
}
foreach ( array_keys( $wp_meta_boxes[ $page ] ) as $a_context ) {
foreach ( array( 'high', 'core', 'default', 'low' ) as $a_priority ) {
if ( ! isset( $wp_meta_boxes[ $page ][ $a_context ][ $a_priority ][ $id ] ) ) {
continue;
}
// If a core box was previously removed, don't add.
if ( ( 'core' === $priority || 'sorted' === $priority )
&& false === $wp_meta_boxes[ $page ][ $a_context ][ $a_priority ][ $id ]
) {
return;
}
// If a core box was previously added by a plugin, don't add.
if ( 'core' === $priority ) {
/*
* If the box was added with default priority, give it core priority
* to maintain sort order.
*/
if ( 'default' === $a_priority ) {
$wp_meta_boxes[ $page ][ $a_context ]['core'][ $id ] = $wp_meta_boxes[ $page ][ $a_context ]['default'][ $id ];
unset( $wp_meta_boxes[ $page ][ $a_context ]['default'][ $id ] );
}
return;
}
// If no priority given and ID already present, use existing priority.
if ( empty( $priority ) ) {
$priority = $a_priority;
/*
* Else, if we're adding to the sorted priority, we don't know the title
* or callback. Grab them from the previously added context/priority.
*/
} elseif ( 'sorted' === $priority ) {
$title = $wp_meta_boxes[ $page ][ $a_context ][ $a_priority ][ $id ]['title'];
$callback = $wp_meta_boxes[ $page ][ $a_context ][ $a_priority ][ $id ]['callback'];
$callback_args = $wp_meta_boxes[ $page ][ $a_context ][ $a_priority ][ $id ]['args'];
}
// An ID can be in only one priority and one context.
if ( $priority !== $a_priority || $context !== $a_context ) {
unset( $wp_meta_boxes[ $page ][ $a_context ][ $a_priority ][ $id ] );
}
}
}
if ( empty( $priority ) ) {
$priority = 'low';
}
if ( ! isset( $wp_meta_boxes[ $page ][ $context ][ $priority ] ) ) {
$wp_meta_boxes[ $page ][ $context ][ $priority ] = array();
}
$wp_meta_boxes[ $page ][ $context ][ $priority ][ $id ] = array(
'id' => $id,
'title' => $title,
'callback' => $callback,
'args' => $callback_args,
);
}
Class
This is an example of how to add a meta box from inside a class
Callback args
The
$callback_args
array will be passed to the callback function as the second argument. The first argument is the post’s$post
object.add_meta_box()
. The argument only contains a subset of the data passed in. Further, the definition on this page currently says: “(array) (Optional) Data that should be set as the $args property of the box array (which is the second parameter passed to your callback).” Yes, that says “the box array”, and that $args is a property of that. But it’s not clear that the second parameter is this “mostly complete” array of metabox data. Without careful reading I think one could confuse this “property of an array” relationship with a “parameter of a method” relationship, leading someone to try a callback likemy_callback($post,$args)
rather thanmy_callback($post,$box_data)
, and then referencing$box_data['args']['foo']
. So this example by @Codex is very helpful but I think more info in the descriptions would provide some clarity and detail that doesn’t need to be realized with an example down in this page.This is the way to register menu screen metabox :)
Seems to me this page should reference the ‘__block_editor_compatible_meta_box’ and ‘__back_compat_meta_box’ options for $callback_args as described in this article: https://make.wordpress.org/core/2018/11/07/meta-box-compatibility-flags/
An often forgotten, but also very important, fact is that any
save_post
handler should check for a multisite switched context. Here’s an example of such guard:That ensures compatibility with other plugins that uses
switch_to_blog()
while they are working on thesave_post
hook. If they are callingwp_insert_post()
again on other sites, your code would overwrite the wrong content without this check.Example:
This is how the metabox data should be processed in the
save_post
action.Not only is the second parameter
$title
required. If$title
is an empty string or the string"0"
, the meta box will not be rendered.This is an example of how to add a meta box from inside a class with textarea. Replace tabs post type with your custom post type name.
How to add metabox in custom post type:
Use same Meta Box for multiple post_type
Slight gotcha for comments metabox
If you need to add a metabox to the comment edit screen, you have to pass in the value ‘
normal
‘ for the$context
parameter.In Plugin context:
Add multiple meta boxes for custom post type.
From WordPress 4.4 the $screen arg can be an array, which greatly simplifies mass additions or alterations of meta boxes. The following code changes the title of the “Author” meta box to “Editor” on pages, posts, attachments, and all custom post types no matter how many are added or when they are added to your site.
Sorry didn’t find any edit option. The last function should be declared as static:
This is how it can be called within a class:
You have $screen = null in the function call but no check and balances for if it IS null. This was causing an error warning when error logging was turned on.
should be replaced with..
not
IMHO
Best,
Design Drumm