1
\$\begingroup\$

Is it possible to call multiple metaboxes in Wordpress with less duplicate functions? For instance, these are my current metaboxes (3 of them, one is a checkbox and two others are text input fields):

/*
 * STICKY POSTS
 *
*/

function add_sticky_metabox(){
    add_meta_box(
        'sticky_post_metabox', 'Sticky Post', 'output_sticky_metabox', 'post'
    );
}
add_action('add_meta_boxes', 'add_sticky_metabox');

// Make a post sticky
function output_sticky_metabox($post){

    /** Grab the current 'my_sticky_post' option value */
    $sp = intval(get_option('sticky_post'));

    /** Check to see if the 'my_sticky_post' option should be disabled or checked for the current Post */
    $checked = checked($sp, $post->ID, false);
    if($sp > 0) :
        $disabled = (!disabled($sp, $post->ID, false)) ? 'disabled="true"' : '';
    else :
        $disabled = '';
    endif;

    /** Add a nonce field */
    wp_nonce_field('sticky_post_metabox', 'sticky_post_metabox_nonce');

    /** Add a hidden field to check against in case it is unchecked before save */
    $value = ($checked) ? '1' : '0';
    echo '<input type="hidden" name="was_checked" value="' . $value . '" />';

    /** Output the checkbox and label */
    echo '<label for="sticky_post">';
    echo '<input type="checkbox" id="sticky_post" name="sticky_post" value="' . $post->ID . '" ' . $checked . $disabled . '>';
    echo 'Maak van dit bericht de highlight?</label>';

    /** Let the user know which Post is currently sticky */
    switch($sp) :

        case 0:
            $message = 'Er is momenteel geen highlight.';
            break;
        case $post->ID:
            $message = 'Dit bericht is de highlight!';
            break;
        default:
            $message = '<a href="' . get_edit_post_link($sp) . '" title="' . the_title_attribute('before=Bewerk bericht \'&after=\'&echo=0') . '">' . get_the_title($sp) . '</a> is momenteel de highlight';
            $message.= '<br />Je moet de highlight status van dat bericht verwijderen voor je deze kan highlighten. Dat is gedaan zodat er geen meerdere highlights kunnen zijn.';

    endswitch;
    echo '<p><em>' . $message .'</em></p>';

}


function save_sticky_metabox($post_id){
    /*
     * We need to verify this came from our screen and with proper authorization,
     * because the save_post action can be triggered at other times.
     */

    /** Ensure that a nonce is set */
    if(!isset($_POST['sticky_post_metabox_nonce'])) :
        return;
    endif;

    /** Ensure that the nonce is valid */
    if(!wp_verify_nonce( $_POST['sticky_post_metabox_nonce'], 'sticky_post_metabox')) :
        return;
    endif;

    /** Ensure that an AUTOSAVE is not taking place */
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) :
        return;
    endif;

    /** Ensure that the user has permission to update this option */
    if(!current_user_can('edit_post', $post_id)) :
        return;
    endif;

    /**
     * Everything is valid, now the option can be updated
     */

    /** Check to see if the 'my_sticky_post' option was checked */
    if(isset($_POST['sticky_post'])) : // It was...

        update_option('sticky_post', $_POST['sticky_post']);  // Update the option

    else : // It was not...

        /** Check to see if the option was checked prior to the options being updated */
        if(isset($_POST['was_checked'])) : // It was...

            update_option('sticky_post', 0); // Set the option to '0'

        endif;

    endif;

}
add_action('save_post', 'save_sticky_metabox');


/*
 * Source
 *
*/

function add_source_metabox(){
    add_meta_box(
        'source_post_metabox', 'Bron', 'output_source_metabox', 'post'
    );
}
add_action('add_meta_boxes', 'add_source_metabox');

function output_source_metabox($post){
    wp_nonce_field('source_post_metabox', 'source_post_metabox_nonce');
    $post_source = $post->post_source;

    echo '<label for="source_post">';
    echo '<input type="text" id="source_post" name="source_post" value="'.$post_source.'" style="width: 80%;max-width: 720px;">';
    echo ' Voer hier de bron van je bericht in.</label>';
    echo '<p>Bv. <em>http://tweakers.net/nieuws/101372/ing-belgie-wil-betalingsgedrag-van-klanten-meer-gebruiken-voor-dienstverlening.html</em></p>';

}
function save_source_metabox($post_id){
    /*
     * We need to verify this came from our screen and with proper authorization,
     * because the save_post action can be triggered at other times.
     */

    /** Ensure that a nonce is set */
    if(!isset($_POST['source_post_metabox_nonce'])) :
        return;
    endif;

    /** Ensure that the nonce is valid */
    if(!wp_verify_nonce( $_POST['source_post_metabox_nonce'], 'source_post_metabox')) :
        return;
    endif;

    /** Ensure that an AUTOSAVE is not taking place */
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) :
        return;
    endif;

    /** Ensure that the user has permission to update this option */
    if(!current_user_can('edit_post', $post_id)) :
        return;
    endif;

    // Update and save the field so it can be used in our template
    if ( isset( $_POST['source_post'] ) ) {
        $data = sanitize_text_field( $_POST['source_post'] );
        update_post_meta( $post_id, 'post_source', $data );
    }

}
add_action('save_post', 'save_source_metabox');


/*
 * Reviews name field
 *
*/

function add_review_metabox(){
    add_meta_box(
        'review_post_metabox', 'Review', 'output_review_metabox', 'post'
    );
}
add_action('add_meta_boxes', 'add_review_metabox');

function output_review_metabox($post){
    wp_nonce_field('review_post_metabox', 'review_post_metabox_nonce');
    $post_review = $post->post_review;

    echo '<label for="review_post">';
    echo '<input type="text" id="review_post" name="review_post" value="'.$post_review.'" style="width: 80%;max-width: 720px;">';
    echo ' Voer hier de naam van het gereviewde apparaat in, zo kort mogelijk.</label>';
    echo '<p>Bv. <em>Lumia 930</em></p>';

}
function save_review_metabox($post_id){
    /*
     * We need to verify this came from our screen and with proper authorization,
     * because the save_post action can be triggered at other times.
     */

    /** Ensure that a nonce is set */
    if(!isset($_POST['review_post_metabox_nonce'])) :
        return;
    endif;

    /** Ensure that the nonce is valid */
    if(!wp_verify_nonce( $_POST['review_post_metabox_nonce'], 'review_post_metabox')) :
        return;
    endif;

    /** Ensure that an AUTOSAVE is not taking place */
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) :
        return;
    endif;

    /** Ensure that the user has permission to update this option */
    if(!current_user_can('edit_post', $post_id)) :
        return;
    endif;

    // Update and save the field so it can be used in our template
    if ( isset( $_POST['review_post'] ) ) {
        $data = sanitize_text_field( $_POST['review_post'] );
        update_post_meta( $post_id, 'post_review', $data );
    }

}
add_action('save_post', 'save_review_metabox');

As you can see there is a lot of duplication, especially in the save functions. However, I'm not sure that this can be put together, because if you do, won't that affect how things are saved? How would I go about putting less load on the server by running as few functions as possible, but with the same functionality?

\$\endgroup\$
2
\$\begingroup\$

As we've already discussed, you can call all 3 metaboxes from the same add_meta_boxes callback, but you can also use just one save_post callback to validate/update if you wish.


Add the metaboxes

add_action('add_meta_boxes', 'add_post_metaboxes');
function add_post_metaboxes(){

    add_meta_box('sticky_post_metabox', 'Sticky Post', 'output_sticky_metabox', 'post');
    add_meta_box('source_post_metabox', 'Bron', 'output_source_metabox', 'post');
    add_meta_box('review_post_metabox', 'Review', 'output_review_metabox', 'post');

}

Populate the metaboxes

For this, to the best of my knowledge, you have to use a separate callback for each matabox. If you were able to pass the name of the option to the funciton, you could then use a switch statement, but as far as I can tell you can't. It's no biggy thoough, it's probably easier to manage this way.


Save the metabox data

Note in this case that the choice is yours. There is nothing wrong with doing it the way you currently are, but this is anouther option. Your validation is simple enough though, so I'd suggest you don't need to use separate callbacks for each piece of data, but the choice is yours...

function save_metabox_data($post_id){

    /*
     * We need to verify this came from our screen and with proper authorization,
     * because the save_post action can be triggered at other times.
     */

    /** Ensure that a nonce is set */
    if(
        !isset($_POST['review_post_metabox_nonce'])
        || !isset($_POST['source_post_metabox_nonce'])
        || !isset($_POST['sticky_post_metabox_nonce'])
    ) :
        return;
    endif;

    /** Ensure that the nonce is valid */
    if(
        !wp_verify_nonce( $_POST['review_post_metabox_nonce'], 'review_post_metabox')
        || !wp_verify_nonce( $_POST['source_post_metabox_nonce'], 'source_post_metabox')
        || !wp_verify_nonce( $_POST['sticky_post_metabox_nonce'], 'sticky_post_metabox')
    ) :
        return;
    endif;

    /** Ensure that an AUTOSAVE is not taking place */
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) :
        return;
    endif;

    /** Ensure that the user has permission to update this option */
    if(!current_user_can('edit_post', $post_id)) :
        return;
    endif;

    /**
     * Everything is valid, now the custom data can be updated
     */

    /** Check to see if the 'my_sticky_post' option was checked */
    if(isset($_POST['sticky_post'])) : // It was...

        update_option('sticky_post', $_POST['sticky_post']);  // Update the option

    else : // It was not...

        /** Check to see if the option was checked prior to the options being updated */
        if($_POST['was_checked'] != 0) : // It was...

            update_option('sticky_post', 0); // Set the option to '0'

        endif;

    endif;

    /** Update and save the field so it can be used in our template */
    if ( isset( $_POST['source_post'] ) ) {
        $data = sanitize_text_field( $_POST['source_post'] );
        update_post_meta( $post_id, 'post_source', $data );
    }

    /** Update and save the field so it can be used in our template */
    if ( isset( $_POST['review_post'] ) ) {
        $data = sanitize_text_field( $_POST['review_post'] );
        update_post_meta( $post_id, 'post_review', $data );
    }

}
add_action('save_post', 'save_metabox_data');
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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