Basic Usage

Justin Sternberg edited this page Oct 8, 2017 · 45 revisions


  1. Home

  2. Installation
    Installation instructions for various environments

  3. Basic Usage
    Get up and running

  4. Advanced Usage
    Not for the faint of heart

  5. Field Types
    Breakdown of field types

  6. Examples
    Examples for registering fields

  7. Field Parameters
    Breakdown of common field parameters

  8. Display Options
    Limit display of boxes

  9. Box Properties
    Breakdown of box properties

  10. Troubleshooting
    Common issues & how to deal with them

  11. Notable Changes in CMB2 (from original CMB)
    CMB2 — a complete re-write

  12. Tips & Tricks
    10x your CMB2 skills

  13. REST API
    CMB2 data through WordPress REST API

  14. Javascript API
    Work with CMB2 JS events & hooks

Advanced tutorials:

External Resources:

Clone this wiki locally

Table of Contents generated with DocToc

This code is designed to be run inside themes and plugins. Proper structure would look like:


Quick Start

Open example-functions.php and copy/paste all of the code into functions.php. Create a new page and you should see all the example metaboxes in the page editor. Use get_post_meta() to get/use the data.

Getting Started

First, you need to get the bootstrap and start the engine. To do so, add the following code to functions.php. There are some caveats to including CMB2 in your plugin or theme. Please review them belo..

Note: If you are installing the plugin from, you can skip this step as it is handled by the plugin.

 * Get the bootstrap!
 * (Update path to use cmb2 or CMB2, depending on the name of the folder.
 * Case-sensitive is important on some systems.)
require_once __DIR__ . '/cmb2/init.php';


  • init.php needs to be required outside any hook. It needs to be loaded as early as possible.
  • Do not do any kind of conditional loading, e.g. if ( ! class_exists..... CMB2 will handle that.

Create a metabox

Now that you've included the CMB2 engine, you can start adding metaboxes with the following code inside functions.php:

add_action( 'cmb2_admin_init', 'cmb2_sample_metaboxes' );
 * Define the metabox and field configurations.
function cmb2_sample_metaboxes() {

	// Start with an underscore to hide fields from custom fields list
	$prefix = '_yourprefix_';

	 * Initiate the metabox
	$cmb = new_cmb2_box( array(
		'id'            => 'test_metabox',
		'title'         => __( 'Test Metabox', 'cmb2' ),
		'object_types'  => array( 'page', ), // Post type
		'context'       => 'normal',
		'priority'      => 'high',
		'show_names'    => true, // Show field names on the left
		// 'cmb_styles' => false, // false to disable the CMB stylesheet
		// 'closed'     => true, // Keep the metabox closed by default
	) );

	// Regular text field
	$cmb->add_field( array(
		'name'       => __( 'Test Text', 'cmb2' ),
		'desc'       => __( 'field description (optional)', 'cmb2' ),
		'id'         => $prefix . 'text',
		'type'       => 'text',
		'show_on_cb' => 'cmb2_hide_if_no_cats', // function should return a bool value
		// 'sanitization_cb' => 'my_custom_sanitization', // custom sanitization callback parameter
		// 'escape_cb'       => 'my_custom_escaping',  // custom escaping callback parameter
		// 'on_front'        => false, // Optionally designate a field to wp-admin only
		// 'repeatable'      => true,
	) );

	// URL text field
	$cmb->add_field( array(
		'name' => __( 'Website URL', 'cmb2' ),
		'desc' => __( 'field description (optional)', 'cmb2' ),
		'id'   => $prefix . 'url',
		'type' => 'text_url',
		// 'protocols' => array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet'), // Array of allowed protocols
		// 'repeatable' => true,
	) );

	// Email text field
	$cmb->add_field( array(
		'name' => __( 'Test Text Email', 'cmb2' ),
		'desc' => __( 'field description (optional)', 'cmb2' ),
		'id'   => $prefix . 'email',
		'type' => 'text_email',
		// 'repeatable' => true,
	) );

	// Add other metaboxes as needed


Note: For more metabox examples, see example-functions.php

Here is a cool video overview of what you will get with the example-functions.php file:

video overview of what you will get with the example-functions.php file

Creating the metabox using a plugin

You can also create the metabox by creating a standard WordPress plugin and simply pasting the above code below the header of the plugin.

Display the Metadata

Finally, you need to be able to extract the metadata and put it to work. In your theme or plugin file, use the get_post_meta() function to display your metadata. Remember, you must pass the post ID!

// Grab the metadata from the database
$text = get_post_meta( get_the_ID(), '_yourprefix_text', true );

// Echo the metadata
echo esc_html( $text );

Let's assume you created a metabox with the field outlined above, and want to display this on the single page template:

 * The template for displaying all pages.
 * This is the template that displays all pages by default.
 * Please note that this is the WordPress construct of pages
 * and that other 'pages' on your WordPress site will use a
 * different template.
 * @package WordPress
 * @subpackage Twenty_Eleven
 * @since Twenty Eleven 1.0

get_header(); ?>

		<div id="primary">
			<div id="content" role="main">

				<?php while ( have_posts() ) : the_post(); ?>

					<?php get_template_part( 'content', 'page' ); ?>

					$text  = get_post_meta( get_the_ID(), '_yourprefix_text', true );
					$email = get_post_meta( get_the_ID(), '_yourprefix_email', true );
					$url   = get_post_meta( get_the_ID(), '_yourprefix_url', true );
					echo esc_html( $text );
					echo is_email( $email );
					echo esc_url( $url );

					<?php comments_template( '', true ); ?>

				<?php endwhile; // end of the loop. ?>

			</div><!-- #content -->
		</div><!-- #primary -->

<?php get_footer(); ?>

For more information on working with post meta, see the Codex page for get_post_meta(), or check out the Post Meta Bootcamp. Remember, to escape any and all data! Using proper data validation when working with post meta is the right thing to do. Trust no one!

For more example code, see example-functions.php

Adding metaboxes to user profile

To add custom metaboxes to the user profile page, you can set the object_types parameter to array( 'user' ) to indicate that the metaboxes should be displayed on the user profile (rather than a specific post type) and that the meta information should be stored against user_meta, rather than post_meta.

An example metabox can be seen in example-functions.php

Note that the Metabox description and name parameters will not display. You can label your user settings section by adding a title field as the first field.

Caveats for bundling and including CMB2.

This section is to hightlight some dos/don'ts for including CMB2. CMB2 has an intelligent method for loading only one version of itself and only the newest version. If you do not include it properly, it will likely result in unintended consequences. For more background info about how/why CMB2 does it this way, read this post.

  • Do: Include the files directly from your theme or plugin. E.g.:

     require_once  __DIR__ . '/includes/cmb2/init.php';

    Don't: Include the files from a hook. E.g.:

     // DON'T DO THIS
     add_action( 'init', 'wprpt_initialize_cmb_init', 10 );
     function wprpt_initialize_cmb_init() {
     	require_once  __DIR__ . '/includes/cmb2/init.php';
  • Do: Use case-sensitive paths to the include file. E.g.:

     require_once  __DIR__ . '/includes/CMB2/init.php';


     require_once  __DIR__ . '/includes/cmb2/init.php';

    Don't: Use a class_exists() check before including. (CMB2 handles that magic on it's own.)

     // DON'T DO THIS
     if ( ! class_exists( 'Some_CMB2_Class' ) ) {
     	require_once  __DIR__ . '/includes/cmb2/init.php';