I've simplified a problem of saving custom metaboxes on update and still can't get the box to save the custom-field input to the database.

This is the call from functions.php to an external file /metaboxes/home-meta-new.php:

    // Loading Home Page Meta Box Code from External .php file
    add_action( 'add_meta_boxes_page','load_home_meta' );
    function load_home_meta() {
        $post_id = $_GET['post'] ? $_GET['post'] : $_POST['post_ID'];
        if($post_id == '104'){
            include( get_template_directory() . '/metaboxes/home-meta-new.php' );

That part works as it shows the one meta box from the home-meta-new.php file.

Unfortunately, once values are input for the custom-fields and the user clicks update, the post refreshes without saving the values. Here is the home-meta-new.php code:


     * Home Page Custom Meta Content

    'home_meta_box', // $id  
    'Home Page Content', // $title   
    'show_home_meta_box', // $callback  
    'page', // $page  
    'normal', // $context  
    'high'); // $priority       

    // Creating Array for Fields
    $prefix = '_home_';
    global $home_meta_fields;
    $home_meta_fields = array(
            'label' => 'Caption Title',
            'desc' => 'Upper section H2 caption title.',
            'id' => $prefix.'title',
            'type' => 'text'
            'label' => 'Caption Sub Title',
            'desc' => 'Upper section H3 caption title.',
            'id' => $prefix.'sub_title',
            'type' => 'text'
          'label'=> 'Caption',  
          'desc'  => 'Caption text block.',  
          'id'    => $prefix.'caption',  
          'type'  => 'textarea'  
            'label'  => 'Caption Image',  
            'desc'  => 'Upload a pre-cropped 1140px wide x 530px tall web-optimized image.',  
            'id'    => $prefix.'image',  
            'type'  => 'image'  
    );// end home_meta array

    //The Callback
    function show_home_meta_box() {
    global $home_meta_fields, $post;
    // Using nonce for verification
    echo '<input type="hidden" name="home_meta_box_nonce" value="'.wp_create_nonce('home_upper_nonce').'" />';
    //wp_nonce_field( 'home_upper_nonce', 'home_upper_nonce' );

        //Begin field table and loop
        echo '<table class="form-table">';
        foreach ($home_meta_fields as $field) {
            // get value of this field if it exists for this page
            $meta = get_post_meta($post->ID, $field['id'], true);
            // begin a table row with
            echo '<tr>
                            <th><label for="'.$field['id'].'">'.$field['label'].'</label></th>
                            switch($field['type']) {
                                // case items will go here
                                // text  
                                case 'text':  
                                    echo '<input type="text" name="'.$field['id'].'" id="'.$field['id'].'" value="'.$meta.'" size="30" /> 
                                        <br /><span class="description">'.$field['desc'].'</span>';  
                                // textarea  
                                case 'textarea':  
                                    echo '<textarea name="'.$field['id'].'" id="'.$field['id'].'" cols="60" rows="4">'.$meta.'</textarea> 
                                        <br /><span class="description">'.$field['desc'].'</span>';  
                                case 'image':  
                                    $image = get_template_directory_uri().'/library/images/img-preview-blank.png';    
                                    echo '<span class="custom_default_image" style="display:none">'.$image.'</span>';  
                                    if ($meta) { $image = wp_get_attachment_image_src($meta, 'medium'); $image = $image[0]; }                 
                                    echo    '<input name="'.$field['id'].'" type="hidden" class="custom_upload_image" value="'.$meta.'" /> 
                                                <img src="'.$image.'" class="custom_preview_image" style="max-width:300px" alt="" /><br /> 
                                                    <input class="custom_upload_image_button button" type="button" value="Choose Image" /> 
                                                    <small> <a href="#" class="custom_clear_image_button">Remove Image</a></small> 
                                                    <br clear="all" /><span class="description">'.$field['desc'].'';  
                            } // end switch
            echo '</td></tr>';
        } // end foreach
        echo '</table>'; // end table
    }// end build metabox callback

    // Save the Data
    function save_home_meta($post_id) {  
        global $home_meta_fields;  

        // verify nonce 

        //option one 
        //if (!wp_verify_nonce($_POST['home_meta_box_nonce'], basename(__FILE__)))   
            //return $post_id;  

            //option two
            if (isset($_POST['home_meta_box_nonce'])){
                if ( !wp_verify_nonce( $_POST['home_meta_box_nonce'], 'home_upper_nonce' ) )

        // check autosave  
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)  
            return $post_id;  
        // check permissions  
        if ('page' == $_POST['post_type']) {  
            if (!current_user_can('edit_page', $post_id))  
                return $post_id;  
            } elseif (!current_user_can('edit_post', $post_id)) {  
                return $post_id;  

        // loop through fields and save the data  
        foreach ($home_meta_fields as $field) {  
            $old = get_post_meta($post_id, $field['id'], true);  
            $new = $_POST[$field['id']];  
            //if ($new && $new != $old) {  
                    if ($new && ($new != $old)) {
                update_post_meta($post_id, $field['id'], $new);  
            } elseif ('' == $new && $old) {  
                delete_post_meta($post_id, $field['id'], $old);  
        } // end foreach  
    add_action('save_post', 'save_home_meta');
    // end save_home_meta


Anyone able to identify where it's choking on the save? Thanks!

  • 1
    Try adding some dies inside your save_home_meta to see how far your code is getting.
    – vancoder
    Mar 8, 2013 at 18:42

1 Answer 1


When you do that include, you are trying to add the save_post hook inside the add_meta_boxes_$post_type hook. It should be independent.

add_action( 'add_meta_boxes_page','load_home_meta' );
add_action( 'save_post', 'save_home_meta' );

// Declare all callback functions

Also, you shouldn't declare a function inside a function. Maybe you should consider creating a plugin for handling this, see: Where to put my code: plugin or functions.php?.
Or, if you really want it inside your theme's functions.php, do a include for all this meta box code.

You'll find plenty of working examples here, check this search query:
+save_post +add_meta_box is:answer

  • Thanks @brasofilo... Will test that out... Figured that was what I was hanging on. Also, I thought I had done an include in the code above (just bundled the save_post action inside the add_meta_boxes_page action). thx
    – tigre
    Mar 8, 2013 at 20:36

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.