I have a problem with meta boxes that I working on! I'm making a small meta box framework for my theme but I got a weird problem that is the first meta box the first array it's the only one saves data!

I noticed something else may help I have 2 custom post types if I create the whole 2 meta boxes in one post type them both working but if I create a meta box for each post type only the first one what working and saves the data! I think the problem ( not sure ) that I did something wrong with nonce function.

There's my code:

function classy_create_meta_boxes( $args = array() ) {
$defaults = array(
    'id'        => 'default_field',                     // the ID of the setting in our options array, and the ID of the HTML form element
    'title'     => 'Default Title',                     // the label for the HTML form element
    'context'   => 'side',                              // the section this setting belongs to — must match the array key of a section in classy_options_page_sections()
    'callback'  => 'default',
    'priority'  => '',
    'screen'    => '',
    'options'   =>
                'id'    => '',
                'type'  => 'text',
                'key'   => '',
                'single'=> 'true',
                'std'   => '',
                'class' => 'regular-text',
                'desc'  => 'This is a default description'

// "extract" to be able to use the array keys as variables in our function output below
extract( wp_parse_args( $args, $defaults ) );

// additional arguments for use in form field output in the function classy_form_field_fn!
$field_args = array(
    'id'        => $id,
    'callback'  => $callback,
    'priority'  => $priority,
    'context'   => $context,
    'screen'    => $screen,
    'options'   => $options


function classy_metaboxes_options(  ) {
$prefix = "classy_";

$metaboxes[] = array(
    'id'        => $prefix.'messages_email_details_meta_box',
    'title'     => 'Email',
    'screen'    => 'messages',
    'context'   => 'side',
    'priority'  => 'default',
    'options'   => array(
            'id'        => 'form_full_name',
            'type'      => 'text',
            'label'     => 'Full Name',
            'desc'      => 'This is a default description',
            'single'    => true,

            'id'        => 'form_email',
            'type'      => 'email',
            'label'     => 'Email',
            'desc'      => 'This is a default description',
            'single'    => true,

$metaboxes[] = array(
    'id'        => $prefix.'portfolio_gallery_meta_box',
    'title'     => 'Gallery',
    'screen'    => 'portfolio',
    'context'   => 'normal',
    'priority'  => 'default',
    'options'   => array(
            'id'        => 'gallery_meta_box',
            'key'       => '_gallery',
            'single'    => true,
            'type'      => 'gallery'

return $metaboxes;}

function classy_add_meta_box() {

if (!empty( classy_metaboxes_options() )) {
    foreach (classy_metaboxes_options() as $option ) {

function classy_portfolio_gallery_callback( $post, $metaboxes ) {
global $post;
$fields = $metaboxes['args']['options'];

foreach ($fields as $field) {
    switch ($field['type']) {
        case "gallery":
            // Noncename needed to verify where the data originated
            $html = '<input type="hidden" name="'. $field['id'].'_nonce' .'" id="'. $field['id'].'_nonce' .'" value="' .wp_create_nonce( plugin_basename(__FILE__) ). '" />';

            // Get the gallery data if its already been entered
            $gallery = get_post_meta($post->ID, '_classy_'.$field['id'], $field['single']);

            if (empty($gallery))
                $html .= '<a href="#" id="classy_portfolio_gallery_upload">Set gallery images</a><br>';
                $html .= '<a href="#" id="classy_portfolio_gallery_upload">Update gallery images</a><br>';

            $html .= "<input type='hidden' id='classy_portfolio_gallery' name='_classy_{$field['id']}' value='{$gallery}'>";

            $html .= '<div class="classy_images">';
            $gallery_images = explode('|', $gallery);
            $gallery_images = array_filter($gallery_images, function($value) { return $value !== ''; });

            foreach ($gallery_images as $image)
                $html .= '<img height="70" style="display: inline-block" src="'.$image.'" >';
            $html .= "</div>";

            $html .= "<div class='remove-link'></div>";

        case "text":
        case "email":
            // Noncename needed to verify where the data originated
            $html = '<input type="hidden" name="'.$field['id'].'_nonce'.'" id="'.$field['id'].'_nonce'.'" value="' .wp_create_nonce( plugin_basename(__FILE__) ). '" />';
            $val = get_post_meta($post->ID, '_classy_'.$field['id'], $field['single']);
            $html .= "<label for='{$field['id']}' class='description'> {$field['label']}: </label><br>";
            $html .= "<input type='{$field['type']}' style='width: 100%; max-width: 100%' id='{$field['id']}' name='_classy_{$field['id']}' value='{$val}'><br>";
            $html .= "<span class='description'> {$field['desc']} </span><br>";

    echo $html;
function classy_save_portfolio_gallery_meta_box($post_id, $post) {

foreach (classy_metaboxes_options() as $option) {

    foreach ($option['options'] as $field) {

        // verify this came from the our screen and with proper authorization,
        // because save_post can be triggered at other times
        if ( !isset($_POST[$field['id'].'_nonce']) || !wp_verify_nonce($_POST[$field['id'].'_nonce'], plugin_basename(__FILE__) )) {
            return $post->ID;

        // OK, we're authenticated: we need to find and save the data
        // We'll put it into an array to make it easier to loop though.

        $events_meta['_classy_'.$field['id']] = $_POST['_classy_'.$field['id']];

        // Add values of $events_meta as custom fields

        foreach ($events_meta as $key => $value) { // Cycle through the $events_meta array!
            if( $post->post_type == 'revision' ) return; // Don't store custom data twice
            $value = implode(',', (array)$value); // If $value is an array, make it a CSV (unlikely)
            if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
                update_post_meta($post->ID, $key, $value);
            } else { // If the custom field doesn't have a value
                add_post_meta($post->ID, $key, $value);
            if(!$value) delete_post_meta($post->ID, $key); // Delete if blank



1 Answer 1


I found the wrong part is looping the wp_create_nonce() inside function classy_portfolio_gallery_callback I just get it outside the loop and put a fixed name and edit also the save function classy_save_portfolio_gallery_meta_box for specfic the first condition with the new name attr.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.