Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a custom metabox that have 2 options: URL and a text box called "testimonial".

The URL box is working great(when i put some text in this field on admin, the text appears on site), but the testimonial box(same proposal) dont works.

What is wrong or what is missing?

<?php

add_action('admin_init', 'portfolio_meta_init');

function portfolio_meta_init() {
    // add a meta box for WordPress 'project' type
    add_meta_box('portfolio_meta', 'Project Infos', 'portfolio_meta_setup', 'project', 'side', 'low');

    // add a callback function to save any data a user enters in
    add_action('save_post', 'portfolio_meta_save');
}

function portfolio_meta_setup() {
    global $post;
    ?>
    <div class="portfolio_meta_control">
        <label>URL</label>
        <p>
            <input type="text" name="_url" value="<?php echo get_post_meta($post->ID, '_url', TRUE); ?>" style="width: 100%;" />
        </p>

        <label>Testimonial</label>
        <p>
            <input type="text" name="_testimonial" value="<?php echo get_post_meta($post->ID, '_testimonial', TRUE); ?>" style="width: 100%;" />
        </p>
    </div>
    <?php
    // create for validation
    echo '<input type="hidden" name="meta_noncename" value="' . wp_create_nonce(__FILE__) . '" />';
}

function portfolio_meta_save($post_id) {
    // check nonce
    if (!isset($_POST['meta_noncename']) || !wp_verify_nonce($_POST['meta_noncename'], __FILE__)) {
        return $post_id;
    }

    // check capabilities
    if ('post' == $_POST['post_type']) {
        if (!current_user_can('edit_post', $post_id)) {
            return $post_id;
        }
    } elseif (!current_user_can('edit_page', $post_id)) {
        return $post_id;
    }

    // exit on autosave
    if (defined('DOING_AUTOSAVE') == DOING_AUTOSAVE) {
        return $post_id;
    }

    if (isset($_POST['_url'])) {
        update_post_meta($post_id, '_url', $_POST['_url']);
        update_post_meta($post_id, '_testimonial', $_POST['_testimonial']);
    } else {
        delete_post_meta($post_id, '_url');
        delete_post_meta($post_id, '_testimonial');
    }
}

/* --- #end  Demo URL meta box --- */ ?>

The outputs:

<?php echo get_post_meta($post->ID, '_testimonial', TRUE); ?>
<?php echo get_post_meta($post->ID, '_url', TRUE); ?>
share|improve this question
1  
You are checking for $_POST['_url'] and using that to determine what to do with both _url and _testimonial. Is that on purpose? –  s_ha_dum Apr 15 '13 at 21:06
1  
Agree with @s_ha_dum. If you haven't set the $_POST['_url'] then _testimonial will never update. Also, in the future, I would suggest using a more description question title. "It doesn't work/not-working" titles don't help future users. –  helgatheviking Apr 15 '13 at 22:17
1  
ok i will change the title –  Chead Apr 15 '13 at 22:27

1 Answer 1

up vote 0 down vote accepted

Your above code should be working as is.

There is however one logical error at the end of your saving function - you make the saving of both fields dependent on whether $_POST['_url'] is set.
I suppose that is not intentional. You likely want something along the lines of:

if ( isset( $_POST['_url'] ) ) {
    update_post_meta( $post_id, '_url', $_POST['_url'] );
} else {
    delete_post_meta( $post_id, '_url' );
}

if ( isset($_POST['_testimonial'] ) ) {
    update_post_meta( $post_id, '_testimonial', $_POST['_testimonial'] );
} else {
    delete_post_meta( $post_id, '_testimonial' );
}

While the above is likely the functionality you are looking for, it isn't very efficient if you have more than two custom fields to save (or create), so I'd suggest you do something like this:

class WPSE_95952_meta
{
    private $fields = array(
        array(
            'name' => '_url',
            'label' => 'URL'
        ),
        array(
            'name' => '_testimonial',
            'label' => 'Testimonial'
        )
    );

    public function __construct()
    {
        // add a meta box for WordPress 'project' type
        add_action( 'add_meta_boxes', array( $this, 'add_project_box' ) );
        // add a callback function to save any data a user enters in
        add_action( 'save_post', array( $this, 'portfolio_meta_save' ) );
    }

    public function add_project_box()
    {
        add_meta_box(
            'portfolio_meta',
            'Project Infos',
            array( $this, 'portfolio_meta_setup' ),
            'project',
            'side',
            'low'
        );
    }

    public function portfolio_meta_setup()
    {
        global $post;

        $output = '<div class="portfolio_meta_control">';

        foreach ( $this->fields as $field ) {
            $output .= '<label>' . $field['label'] . '</label>' .
                '<p>' .
                    '<input type="text" name="' . $field['name'] .
                        '" value="' . get_post_meta( $post->ID, $field['name'], true ) .
                        '" style="width: 100%;" />' .
                '</p>';
        }

        $output .= '</div>';

        // create for validation
        $output .= '<input type="hidden" name="meta_noncename" value="' .
            wp_create_nonce(__FILE__) . '" />';

        echo $output;
    }

    public function portfolio_meta_save( $post_id )
    {
        // exit on autosave
        if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
            return $post_id;
        }

        // check nonce
        if (
            ! isset( $_POST['meta_noncename'] ) ||
            ! wp_verify_nonce( $_POST['meta_noncename'], __FILE__ )
        ) {
            return $post_id;
        }

        // check capabilities
        if (
            ( 'post' === $_POST['post_type'] && ! current_user_can( 'edit_post', $post_id ) ) ||
            ! current_user_can( 'edit_page', $post_id ) 
        ) {
            return $post_id;
        }

        foreach ( $this->fields as $field ) {
            $old = get_post_meta( $post_id, $field['name'], true );
            $new = isset( $_POST[$field['name']] ) ? $_POST[$field['name']] : false;

            if ( $new && $new != $old ) {
                update_post_meta( $post_id, $field['name'], $new );
            } elseif ( ! $new && $old ) {
                delete_post_meta( $post_id, $field['name'], $old );
            }
        }
    }
}

$wpse_95952_meta = new WPSE_95952_meta();
share|improve this answer
    
i got this error Parse error: syntax error, unexpected ')', expecting T_PAAMAYIM_NEKUDOTAYIM in /home/public_html/website/wordpress/wp-content/themes/mytheme/functions.php on line 247 –  Chead Apr 15 '13 at 21:59
    
Typo. Forgot two $ signs. Corrected. But anyhow: You do not need to copy the above verbosely, it was simply meant as a suggestion to an alternative approach, which would be handy to have if you wanted to add more fields. With the above, all you have to do is expand the $fields array, the rest can remain untouched. Also note that your saving logic will (re-)write values to the database on each save, even if they haven't changed. The above does not do that. –  Johannes Pille Apr 15 '13 at 22:12
    
ok, i understood, but i got this error now with this code: Warning: call_user_func(portfolio_meta_setup) [function.call-user-func]: First argument is expected to be a valid callback in /home/public_html/mytheme/wordpress/wp-admin/includes/template.php on line 927 –  Chead Apr 15 '13 at 22:30
    
Yup, that's again due to a mistake of mine when putting your code inside a class. Again, corrected in the above - change 'portfolio_meta_setup' to array( $this, 'portfolio_meta_setup' ) in the add_meta_box call. Maybe I shoulda left this in procedural code, but it is so much nicer to have the $fields array as a class property rather than passing it from function to function or making it live in the global namespace. –  Johannes Pille Apr 15 '13 at 22:36
    
nice, but not is working the _testimonial output :\ –  Chead Apr 15 '13 at 23:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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