add_meta_box ( string $id, string $title, callable $callback, string|array|WP_Screen $screen = null, string $context = 'advanced', string $priority = 'default', array $callback_args = null )

Adds a meta box to one or more screens.

Source file: wp-admin/includes/template.php

View source


Parameters

$id

(string) (Required) Meta box ID (used in the 'id' attribute for the meta box).

$title

(string) (Required) Title of the meta box.

$callback

(callable) (Required) Function that fills the box with the desired content. The function should echo its output.

$screen

(string|array|WP_Screen) (Optional) 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.

Default value: null

$context

(string) (Optional) The context within the screen where the boxes 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 value: 'advanced'

$priority

(string) (Optional) The priority within the context where the boxes should show ('high', 'low').

Default value: 'default'

$callback_args

(array) (Optional) Data that should be set as the $args property of the box array (which is the second parameter passed to your callback).

Default value: 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 added or removed by a plugin, don't add.
			if ( 'core' == $priority ) {
				// If core box previously deleted, don't add
				if ( false === $wp_meta_boxes[$page][$a_context][$a_priority][$id] )
					return;

				/*
				 * If 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);
}


Changelog

  • Since: WordPress 2.5.0
  • Since: WordPress 4.4.0 The $screen parameter now accepts an array of screen IDs.

User Contributed Notes

  1. /**
     * Register meta box(es).
     */
    function wpdocs_register_meta_boxes() {
    	add_meta_box( 'meta-box-id', __( 'My Meta Box', 'textdomain' ), 'wpdocs_my_display_callback', 'post' );
    }
    add_action( 'add_meta_boxes', 'wpdocs_register_meta_boxes' );
    
    /**
     * Meta box display callback.
     *
     * @param WP_Post $post Current post object.
     */
    function wpdocs_my_display_callback( $post ) {
    	// Display code/markup goes here. Don't forget to include nonces!
    }
    
    /**
     * Save meta box content.
     *
     * @param int $post_id Post ID
     */
    function wpdocs_save_meta_box( $post_id ) {
    	// Save logic goes here. Don't forget to include nonce checks!
    }
    add_action( 'save_post', 'wpdocs_save_meta_box' );
    
  2. 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.

    /**
     * This function adds a meta box with a callback function of my_metabox_callback()
     */
    function add_wpdocs_meta_box() {
    	$var1 = 'this';
    	$var2 = 'that';
    	add_meta_box(
    		'metabox_id',
    		__( 'Metabox Title', 'textdomain' ),
    		'wpdocs_metabox_callback',
    		'page',
    		'normal',
    		'low',
    		array( 'foo' => $var1, 'bar' => $var2 )
    	);
    }
    
    /**
     * Get post meta in a callback
     *
     * @param WP_Post $post    The current post.
     * @param array   $metabox With metabox id, title, callback, and args elements.
     */
    
    function wpdocs_metabox_callback( $post, $metabox ) {
    	// Output last time the post was modified.
    	echo 'Last Modified: ' . $post->post_modified;
    
    	// Output 'this'.
    	echo $metabox['args']['foo'];
    
    	// Output 'that'.
    	echo $metabox['args']['bar'];
    
    	// Output value of custom field.
    	echo get_post_meta( $post->ID, 'wpdocs_custom_field', true );
    }
    
  3. Class
    This is an example of how to add a meta box from inside a class

    /**
     * Calls the class on the post edit screen.
     */
    function call_someClass() {
    	new someClass();
    }
    
    if ( is_admin() ) {
    	add_action( 'load-post.php',     'call_someClass' );
    	add_action( 'load-post-new.php', 'call_someClass' );
    }
    
    /**
     * The Class.
     */
    class someClass {
    
    	/**
    	 * Hook into the appropriate actions when the class is constructed.
    	 */
    	public function __construct() {
    		add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
    		add_action( 'save_post',      array( $this, 'save'         ) );
    	}
    
    	/**
    	 * Adds the meta box container.
    	 */
    	public function add_meta_box( $post_type ) {
    		// Limit meta box to certain post types.
    		$post_types = array( 'post', 'page' );
    
    		if ( in_array( $post_type, $post_types ) ) {
    			add_meta_box(
    				'some_meta_box_name',
    				__( 'Some Meta Box Headline', 'textdomain' ),
    				array( $this, 'render_meta_box_content' ),
    				$post_type,
    				'advanced',
    				'high'
    			);
    		}
    	}
    
    	/**
    	 * Save the meta when the post is saved.
    	 *
    	 * @param int $post_id The ID of the post being saved.
    	 */
    	public function save( $post_id ) {
    
    		/*
    		 * We need to verify this came from the our screen and with proper authorization,
    		 * because save_post can be triggered at other times.
    		 */
    
    		// Check if our nonce is set.
    		if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) {
    			return $post_id;
    		}
    
    		$nonce = $_POST['myplugin_inner_custom_box_nonce'];
    
    		// Verify that the nonce is valid.
    		if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) {
    			return $post_id;
    		}
    
    		/*
    		 * If this is an autosave, our form has not been submitted,
    		 * so we don't want to do anything.
    		 */
    		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    			return $post_id;
    		}
    
    		// Check the user's permissions.
    		if ( 'page' == $_POST['post_type'] ) {
    			if ( ! current_user_can( 'edit_page', $post_id ) ) {
    				return $post_id;
    			}
    		} else {
    			if ( ! current_user_can( 'edit_post', $post_id ) ) {
    				return $post_id;
    			}
    		}
    
    		/* OK, it's safe for us to save the data now. */
    
    		// Sanitize the user input.
    		$mydata = sanitize_text_field( $_POST['myplugin_new_field'] );
    
    		// Update the meta field.
    		update_post_meta( $post_id, '_my_meta_value_key', $mydata );
    	}
    
    
    	/**
    	 * Render Meta Box content.
    	 *
    	 * @param WP_Post $post The post object.
    	 */
    	public function render_meta_box_content( $post ) {
    
    		// Add an nonce field so we can check for it later.
    		wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' );
    
    		// Use get_post_meta to retrieve an existing value from the database.
    		$value = get_post_meta( $post->ID, '_my_meta_value_key', true );
    
    		// Display the form, using the current value.
    		?>
    		<label for="myplugin_new_field">
    			<?php _e( 'Description for this field', 'textdomain' ); ?>
    		</label>
    		<input type="text" id="myplugin_new_field" name="myplugin_new_field" value="<?php echo esc_attr( $value ); ?>" size="25" />
    		<?php
    	}
    }
    
  4. 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.

    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;
    
    … 

    should be replaced with..

    function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
    	global $wp_meta_boxes;
    
    	if ( $screen == null ) {
    $screen = WP_Screen::get( );
    } elseif ( 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 );
    }
    }
    
    $page = $screen->id;
    
    … 

    not

    if ( ! isset( $screen->id ) ) {
            return;
        }

    IMHO

    Best,
    Design Drumm

You must log in before being able to contribute a note.