Meta boxes have caused me significant trouble in WordPress. They seem simple, look simple and quite frankly should be simple, but they always trip me up when I’m attempting to make them. Many of the tutorials online feature lax security, invalid code or are just way too complex. So instead of posting a long drawn out tutorial I’m just going to post the uber simple demo code below in the hope that it will make things easier for the rest of you. Feel free to copy, paste and modify to suit your needs.

Tom McFarlin has written a similar post with his own meta box class, so check that one out too in case you prefer his approach.

This example adds a meta box in the admin panel of your posts post-type and saves that into that posts post-meta. If you can see any ways to improve it errors in the code, please let me know below in the comments 🙂

<?php

/**
 * Add Meta Box to "post" post type
 *
 * @copyright Copyright (c), Ryan Hellyer
 * @license http://www.gnu.org/licenses/gpl.html GPL
 * @author Ryan Hellyer <ryanhellyer@gmail.com>
 * @since 1.0
 */
class Add_Example_Metabox {

	/*
	 * Class constructor.
	 */
	public function __construct() {
		add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
		add_action( 'save_post',      array( $this, 'meta_boxes_save' ), 10, 2 );
	}

	/**
	 * Add admin metabox.
	 */
	public function add_metabox() {
		add_meta_box(
			'example', // ID
			__( 'Example meta box', 'plugin-slug' ), // Title
			array(
				$this,
				'meta_box', // Callback to method to display HTML
			),
			'post', // Post type
			'side', // Context, choose between 'normal', 'advanced', or 'side'
			'high'  // Position, choose between 'high', 'core', 'default' or 'low'
		);
	}

	/**
	 * Output the example meta box.
	 */
	public function meta_box() {

		?>

		<p>
			<label for="_example"><strong><?php _e( 'Example input field', 'plugin-slug' ); ?></strong></label>
			<br />
			<input type="text" name="_example" id="_example" value="<?php echo esc_attr( get_post_meta( get_the_ID(), '_example', true ) ); ?>" />
			<input type="hidden" id="example-nonce" name="example-nonce" value="<?php echo esc_attr( wp_create_nonce( __FILE__ ) ); ?>">
		</p>

		<?php
	}

	/**
	 * Save opening times meta box data.
	 *
	 * @param  int     $post_id  The post ID
	 * @param  object  $post     The post object
	 */
	public function meta_boxes_save( $post_id, $post ) {

		// Only save if correct post data sent
		if ( isset( $_POST['_example'] ) ) {

			// Do nonce security check
			if ( ! wp_verify_nonce( $_POST['example-nonce'], __FILE__ ) ) {
				return;
			}

			// Sanitize and store the data
			$_example = wp_kses_post( $_POST['_example'] );
			update_post_meta( $post_id, '_example', $_example );
		}

	}
 
}
new Add_Example_Metabox;

?>
View of the example meta box code in action.

View of the example meta box code in action.