Please help me understand how to make Multicheck type for metabox. Search for all internet and nothing. Thanks.


@Jan I have a headache from this function. I dont know whats wrong.I'm trying your method but nothing, then I'm trying get_posts but with this method I have too many troubles. With your method I get this error before content:

Warning: urldecode() expects parameter 1 to be string, array given in Z:\home\mysite.net\www\wp-includes\query.php on line 1878

Here is my code:

        $catids = get_post_meta($post->ID,'_mtb_multicheck',false);
        $limit = 10;
        query_posts( array('posts_per_page' => $limit, 'cat' => $catids, 'paged' => get_query_var('paged') ) );
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>

        <!-- Content-->

<?php endwhile; ?>  
            <?php pagination(); ?>
<?php else : ?>
            <!--Error message here-->

<?php endif; ?>

I want to know what my vatiables return. Make this:

query_posts( array('posts_per_page' => $limit, 'cat' => print_r($catids), 'paged' => get_query_var('paged') ) );

and get this on my page:

Array ( [0] => 5 [1] => 5 [2] => 3 )

I think it's my query_posts printed, not $catids. It's a big, big trouble. I feel myself like a nerd. Please help me.

  • @Denis: Your question is not very clear. Do you mean a series of checkboxes by "multicheck"? And are you talking about adding a new metabox, like on the post edit screen?
    – Jan Fabry
    Dec 1, 2010 at 8:40
  • Yes Jan, I want to add a series of checkboxes like on the post edit screen. I make metabox by this tutorial deluxeblogtips.com/2010/05/howto-meta-box-wordpress.html , but they doesn't include type multicheck. Dec 1, 2010 at 13:04
  • @Denis: That code seems to include the checkbox type, how is this different from a "multicheck"? Can you update your question with an mock-up (sketch) image? If you use @ before my name in a comment, like @Jan, I will get a notification and can reply sooner.
    – Jan Fabry
    Dec 2, 2010 at 9:22
  • @Jan: Multicheck mean that you can check multiple item in one field, it's like category taxonomy where we can check several categories that include this post. We dont need to create checkbox for every category or another item we use array with items and multicheck help us check several items. Dec 2, 2010 at 13:07
  • @Jan: I make somthing like this but it's check only one checkbox not several: pastebin.com/TAKDe13u Dec 2, 2010 at 13:32

1 Answer 1


The post metadata can store multiple values either as distinct entries in the postmeta table, or as one entry with the value as a serialized PHP array. The serialization may require less code, but the distinct entries allow faster querying later ("give me all posts that have at least option A of the multicheck checked").

I took the code you linked to and made the following changes to allow a "multicheck":

// in show():
// Line 254: replace it by:
$meta = get_post_meta($post->ID, $field['id'], 'multicheck' != $field['type'] /* If multicheck this can be multiple values */);
// Add the following to the switch:
case 'multicheck':
    foreach ( $field['options'] as $value => $name ) {
        // Append `[]` to the name to get multiple values
        // Use in_array() to check whether the current option should be checked
        echo '<input type="checkbox" name="', $field['id'], '[]" id="', $field['id'], '" value="', $value, '"', in_array( $value, $meta ) ? ' checked="checked"' : '', ' /> ', $name, '<br/>';

// In save():
// Line 358: replace it by:
$old = get_post_meta($post_id, $name, 'multicheck' != $field['type'] /* If multicheck this can be multiple values */);
// Lines 409-413: Wrap them in an else-clause, and prepend them by:
if ( 'multicheck' == $field['type'] ) {
    // Do the saving in two steps: first get everything we don't have yet
    // Then get everything we should not have anymore
    if ( empty( $new ) ) {
        $new = array();
    $aNewToAdd = array_diff( $new, $old );
    $aOldToDelete = array_diff( $old, $new );
    foreach ( $aNewToAdd as $newToAdd ) {
        add_post_meta( $post_id, $name, $newToAdd, false );
    foreach ( $aOldToDelete as $oldToDelete ) {
        delete_post_meta( $post_id, $name, $oldToDelete );
} else {
    // The original lines 409-413

Two extra changes to prevent PHP warnings when WP_DEBUG is enabled:

// Line 337:
if ( ! isset( $_POST['wp_meta_box_nonce'] ) || !wp_verify_nonce($_POST['wp_meta_box_nonce'], basename(__FILE__))) {
// Line 359:
$new = isset( $_POST[$field['id']] ) ? $_POST[$field['id']] : null;

With these changes, you can use a "multicheck" by defining it like this:

    'name' => 'Multicheck',
    'id' => $prefix . 'multicheck',
    'type' => 'multicheck',
    'options' => array(
        'a' => 'Apple',
        'b' => 'Banana',
        'c' => 'Cherry',
  • @Jan: Thank you very much for this answer, it's a big work. One question: As I said above I'm test this function with list of categories. I'm try assign several categories to page and nothing happens, even one category doesn't accept. In my template I'm use $catid = get_post_meta($post->ID,'mtb_category',true); query_posts('cat='.$catid); Maybe you see whats wrong? Thank you! Dec 7, 2010 at 19:45
  • @Denis: The comments are not the best way to do this, maybe you can ask an additional question? Make sure to include all your code, and output of var_dump() along they way, so we know what is going on.
    – Jan Fabry
    Dec 8, 2010 at 13:01
  • @Jan: I check my database and see that my multicheck is saved separate. Looks now: imgur.com/dX76l.png Must be: imgur.com/m2KiI.png I think problem with metaboxes, not with templates. Dec 9, 2010 at 2:27
  • @Denis: That was intentional, that's why I meant with "distinct entries vs. one serialized entry". Your code should be $catids = get_post_meta( $post->ID, 'mtb_category', false); query_posts( array( 'cat' => $catids ) );. And maybe replace query_posts() with get_posts().
    – Jan Fabry
    Dec 9, 2010 at 7:42
  • @Denis: I'm sorry, you should not use cat if you pass an array to query_posts(), but category__in. cat only accepts a comma-separated list of array ID's, but category__in accepts an array of category ID's, like we use here.
    – Jan Fabry
    Dec 16, 2010 at 10:45

Your Answer

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

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