* Include and setup custom metaboxes and fields. (make sure you copy this file to outside the CMB2 directory)
* Be sure to replace all instances of 'yourprefix_' with your project's prefix.
* http://nacin.com/2010/05/11/in-wordpress-prefix-everything/
* @category YourThemeOrPlugin
* @license http://www.opensource.org/licenses/gpl-license.php GPL v2.0 (or later)
* @link https://github.com/CMB2/CMB2
* Get the bootstrap! If using the plugin from wordpress.org, REMOVE THIS!
if ( file_exists( dirname( __FILE__ ) . '/cmb2/init.php' ) ) {
require_once dirname( __FILE__ ) . '/cmb2/init.php';
} elseif ( file_exists( dirname( __FILE__ ) . '/CMB2/init.php' ) ) {
require_once dirname( __FILE__ ) . '/CMB2/init.php';
* Conditionally displays a metabox when used as a callback in the 'show_on_cb' cmb2_box parameter
* @param CMB2 $cmb CMB2 object.
* @return bool True if metabox should show
function yourprefix_show_if_front_page( $cmb ) {
// Don't show this metabox if it's not the front page template.
if ( get_option( 'page_on_front' ) !== $cmb->object_id ) {
* Conditionally displays a field when used as a callback in the 'show_on_cb' field parameter
* @param CMB2_Field $field Field object.
* @return bool True if metabox should show
function yourprefix_hide_if_no_cats( $field ) {
// Don't show this field if not in the cats category.
if ( ! has_tag( 'cats', $field->object_id ) ) {
* Manually render a field.
* @param array $field_args Array of field arguments.
* @param CMB2_Field $field The field object.
function yourprefix_render_row_cb( $field_args, $field ) {
$classes = $field->row_classes();
$id = $field->args( 'id' );
$label = $field->args( 'name' );
$name = $field->args( '_name' );
$value = $field->escaped_value();
$description = $field->args( 'description' );
<div class="custom-field-row <?php echo esc_attr( $classes ); ?>">
<p><label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $label ); ?></label></p>
<p><input id="<?php echo esc_attr( $id ); ?>" type="text" name="<?php echo esc_attr( $name ); ?>" value="<?php echo $value; ?>"/></p>
<p class="description"><?php echo esc_html( $description ); ?></p>
* Manually render a field column display.
* @param array $field_args Array of field arguments.
* @param CMB2_Field $field The field object.
function yourprefix_display_text_small_column( $field_args, $field ) {
<div class="custom-column-display <?php echo esc_attr( $field->row_classes() ); ?>">
<p><?php echo $field->escaped_value(); ?></p>
<p class="description"><?php echo esc_html( $field->args( 'description' ) ); ?></p>
* Conditionally displays a message if the $post_id is 2
* @param array $field_args Array of field parameters.
* @param CMB2_Field $field Field object.
function yourprefix_before_row_if_2( $field_args, $field ) {
if ( 2 == $field->object_id ) {
echo '<p>Testing <b>"before_row"</b> parameter (on $post_id 2)</p>';
echo '<p>Testing <b>"before_row"</b> parameter (<b>NOT</b> on $post_id 2)</p>';
add_action( 'cmb2_admin_init', 'yourprefix_register_demo_metabox' );
* Hook in and add a demo metabox. Can only happen on the 'cmb2_admin_init' or 'cmb2_init' hook.
function yourprefix_register_demo_metabox() {
* Sample metabox to demonstrate each field type included
$cmb_demo = new_cmb2_box( array(
'id' => 'yourprefix_demo_metabox',
'title' => esc_html__( 'Test Metabox', 'cmb2' ),
'object_types' => array( 'page' ), // Post type
// 'show_on_cb' => 'yourprefix_show_if_front_page', // function should return a bool value
// 'context' => 'normal',
// 'show_names' => true, // Show field names on the left
// 'cmb_styles' => false, // false to disable the CMB stylesheet
// 'closed' => true, // true to keep the metabox closed by default
// 'classes' => 'extra-class', // Extra cmb2-wrap classes
// 'classes_cb' => 'yourprefix_add_some_classes', // Add classes through a callback.
* The following parameter is any additional arguments passed as $callback_args
* to add_meta_box, if/when applicable.
* CMB2 does not use these arguments in the add_meta_box callback, however, these args
* are parsed for certain special properties, like determining Gutenberg/block-editor
* - Make sure default editor is used as metabox is not compatible with block editor
* [ '__block_editor_compatible_meta_box' => false/true ]
* - Or declare this box exists for backwards compatibility
* [ '__back_compat_meta_box' => false ]
* More: https://wordpress.org/gutenberg/handbook/extensibility/meta-box/
// 'mb_callback_args' => array( '__block_editor_compatible_meta_box' => false ),
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Text', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_text',
'show_on_cb' => 'yourprefix_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
// 'column' => true, // Display field value in the admin post-listing columns
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Text Small', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textsmall',
// 'name' => esc_html__( 'Column Title', 'cmb2' ), // Set the admin column title
// 'position' => 2, // Set as the second column.
// 'display_cb' => 'yourprefix_display_text_small_column', // Output the display of the column values through a callback.
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Text Medium', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textmedium',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Read-only Disabled Field', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_readonly',
'default' => esc_attr__( 'Hey there, I\'m a read-only field', 'cmb2' ),
'save_field' => false, // Disables the saving of this field.
'disabled' => 'disabled',
'readonly' => 'readonly',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Custom Rendered Field', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_render_row_cb',
'render_row_cb' => 'yourprefix_render_row_cb',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Website URL', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_url',
// 'protocols' => array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet'), // Array of allowed protocols
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Text Email', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_email',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Time', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_time',
// 'time_format' => 'H:i', // Set to 24hr format
$cmb_demo->add_field( array(
'name' => esc_html__( 'Time zone', 'cmb2' ),
'desc' => esc_html__( 'Time zone', 'cmb2' ),
'id' => 'yourprefix_demo_timezone',
'type' => 'select_timezone',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Date Picker', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textdate',
// 'date_format' => 'Y-m-d',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Date Picker (UNIX timestamp)', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textdate_timestamp',
'type' => 'text_date_timestamp',
// 'timezone_meta_key' => 'yourprefix_demo_timezone', // Optionally make this field honor the timezone selected in the select_timezone specified above
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Date/Time Picker Combo (UNIX timestamp)', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_datetime_timestamp',
'type' => 'text_datetime_timestamp',
// This text_datetime_timestamp_timezone field type
// is only compatible with PHP versions 5.3 or above.
// Feel free to uncomment and use if your server meets the requirement
// $cmb_demo->add_field( array(
// 'name' => esc_html__( 'Test Date/Time Picker/Time zone Combo (serialized DateTime object)', 'cmb2' ),
// 'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
// 'id' => 'yourprefix_demo_datetime_timestamp_timezone',
// 'type' => 'text_datetime_timestamp_timezone',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Money', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textmoney',
// 'before_field' => '£', // override '$' symbol if needed
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Color Picker', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_colorpicker',
// 'alpha' => true, // Make this a rgba color picker.
// 'attributes' => array(
// 'data-colorpicker' => json_encode( array(
// 'palettes' => array( '#3dd0cc', '#ff834c', '#4fa2c0', '#0bc991', ),
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Text Area', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textarea',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Text Area Small', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textareasmall',
'type' => 'textarea_small',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Text Area for Code', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_textarea_code',
'type' => 'textarea_code',
// 'attributes' => array(
// // Optionally override the code editor defaults.
// 'data-codeeditor' => json_encode( array(
// 'codemirror' => array(
// 'lineNumbers' => false,
// To keep the previous formatting, you can disable codemirror.
// 'options' => array( 'disable_codemirror' => true ),
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Title Weeeee', 'cmb2' ),
'desc' => esc_html__( 'This is a title description', 'cmb2' ),
'id' => 'yourprefix_demo_title',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Select', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_select',
'show_option_none' => true,
'standard' => esc_html__( 'Option One', 'cmb2' ),
'custom' => esc_html__( 'Option Two', 'cmb2' ),
'none' => esc_html__( 'Option Three', 'cmb2' ),
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Radio inline', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_radio_inline',
'type' => 'radio_inline',
'show_option_none' => 'No Selection',
'standard' => esc_html__( 'Option One', 'cmb2' ),
'custom' => esc_html__( 'Option Two', 'cmb2' ),
'none' => esc_html__( 'Option Three', 'cmb2' ),
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Radio', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_radio',
'option1' => esc_html__( 'Option One', 'cmb2' ),
'option2' => esc_html__( 'Option Two', 'cmb2' ),
'option3' => esc_html__( 'Option Three', 'cmb2' ),
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Taxonomy Radio', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_text_taxonomy_radio',
'type' => 'taxonomy_radio', // Or `taxonomy_radio_inline`/`taxonomy_radio_hierarchical`
'taxonomy' => 'category', // Taxonomy Slug
// 'inline' => true, // Toggles display to inline
// Optionally override the args sent to the WordPress get_terms function.
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Taxonomy Select', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_taxonomy_select',
'type' => 'taxonomy_select', // Or `taxonomy_select_hierarchical`
'taxonomy' => 'category', // Taxonomy Slug
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Taxonomy Multi Checkbox', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_multitaxonomy',
'type' => 'taxonomy_multicheck', // Or `taxonomy_multicheck_inline`/`taxonomy_multicheck_hierarchical`
'taxonomy' => 'post_tag', // Taxonomy Slug
// 'inline' => true, // Toggles display to inline
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Checkbox', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_checkbox',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Multi Checkbox', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_multicheckbox',
// 'multiple' => true, // Store values in individual rows
'check1' => esc_html__( 'Check One', 'cmb2' ),
'check2' => esc_html__( 'Check Two', 'cmb2' ),
'check3' => esc_html__( 'Check Three', 'cmb2' ),
// 'inline' => true, // Toggles display to inline
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test wysiwyg', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_demo_wysiwyg',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Test Image', 'cmb2' ),
'desc' => esc_html__( 'Upload an image or enter a URL.', 'cmb2' ),
'id' => 'yourprefix_demo_image',
$cmb_demo->add_field( array(
'name' => esc_html__( 'Multiple Files', 'cmb2' ),
'desc' => esc_html__( 'Upload or add multiple images/attachments.', 'cmb2' ),
'id' => 'yourprefix_demo_file_list',
'preview_size' => array( 100, 100 ), // Default: array( 50, 50 )
$cmb_demo->add_field( array(
'name' => esc_html__( 'oEmbed', 'cmb2' ),
/* translators: %s: link to codex.wordpress.org/Embeds */
esc_html__( 'Enter a youtube, twitter, or instagram URL. Supports services listed at %s.', 'cmb2' ),
'<a href="https://wordpress.org/support/article/embeds/">codex.wordpress.org/Embeds</a>'
'id' => 'yourprefix_demo_embed',
$cmb_demo->add_field( array(
'name' => 'Testing Field Parameters',
'id' => 'yourprefix_demo_parameters',
'before_row' => 'yourprefix_before_row_if_2', // callback.
'before' => '<p>Testing <b>"before"</b> parameter</p>',
'before_field' => '<p>Testing <b>"before_field"</b> parameter</p>',
'after_field' => '<p>Testing <b>"after_field"</b> parameter</p>',
'after' => '<p>Testing <b>"after"</b> parameter</p>',
'after_row' => '<p>Testing <b>"after_row"</b> parameter</p>',
add_action( 'cmb2_admin_init', 'yourprefix_register_about_page_metabox' );
* Hook in and add a metabox that only appears on the 'About' page
function yourprefix_register_about_page_metabox() {
* Metabox to be displayed on a single page ID
$cmb_about_page = new_cmb2_box( array(
'id' => 'yourprefix_about_metabox',
'title' => esc_html__( 'About Page Metabox', 'cmb2' ),
'object_types' => array( 'page' ), // Post type
'show_names' => true, // Show field names on the left
), // Specific post IDs to display this metabox
$cmb_about_page->add_field( array(
'name' => esc_html__( 'Test Text', 'cmb2' ),
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
'id' => 'yourprefix_about_text',
add_action( 'cmb2_admin_init', 'yourprefix_register_repeatable_group_field_metabox' );