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.

Basically I need to add custom meta boxes to pages and one of this options must be a list of categories from previous posts. I've managed to add the metaboxes and wrapped the categories in a array, however there must be something I missing as on the page, only the first letter of the category name is being displayed. Here's a screenshot of the result: screenshot of the problem

I can't figure it out what I'm missing. Here's the code for the metabox:

            // Check if is page-homepage.php template
        $post_id = (isset($_GET['post'])) ? $_GET['post'] : ((isset($_POST['post_ID'])) ? $_POST['post_ID'] : false);

        if ($post_id) : 
        $post_template = get_post_meta($post_id, '_wp_page_template', true);
        if ($post_template == 'page-homepage.php') {

        // Add the Meta Box
        function home_custom_meta_box() {
            add_meta_box(
                'home_meta_box', // $id
                'Custom Meta Box', // $title 
                'home_show_custom_meta_box', // $callback
                'page', // $page
                'normal', // $context
                'high'); // $priority
        }
        add_action('add_meta_boxes', 'home_custom_meta_box');

        // Field Array
        $prefix = 'custom_';
        $home_custom_meta_fields = array(
            array(
                'label' => 'Title for the middle column',
                'desc'  => 'Optional',
                'id'    => $prefix.'title1',
                'type'  => 'text'
            ),
                array(
                'label' => 'Category',
                'id'    => $prefix.'category',
                'type'  => 'select',
                'options' => $wp_cats
            ),
            array(
                'label' => 'Title for the right column',
                'desc'  => 'Optional',
                'id'    => $prefix.'title2',
                'type'  => 'text'
            ),
            array(
                'label' => 'Textarea',
                'desc'  => 'A description for the field.',
                'id'    => $prefix.'textarea',
                'type'  => 'textarea'
            ),
            array(
                'label' => 'Checkbox Input',
                'desc'  => 'A description for the field.',
                'id'    => $prefix.'checkbox',
                'type'  => 'checkbox'
            ),
            array(
                'label' => 'Select Box',
                'desc'  => 'A description for the field.',
                'id'    => $prefix.'select',
                'type'  => 'select',
                'options' => array (
                    'one' => array (
                        'label' => 'Option One',
                        'value' => 'one'
                    ),
                    'two' => array (
                        'label' => 'Option Two',
                        'value' => 'two'
                    ),
                    'three' => array (
                        'label' => 'Option Three',
                        'value' => 'three'
                    )
                )
            ),
            array (
                'label' => 'Radio Group',
                'desc'  => 'A description for the field.',
                'id'    => $prefix.'radio',
                'type'  => 'radio',
                'options' => array (
                    'one' => array (
                        'label' => 'Option One',
                        'value' => 'one'
                    ),
                    'two' => array (
                        'label' => 'Option Two',
                        'value' => 'two'
                    ),
                    'three' => array (
                        'label' => 'Option Three',
                        'value' => 'three'
                    )
                )
            ),
            array (
                'label' => 'Checkbox Group',
                'desc'  => 'A description for the field.',
                'id'    => $prefix.'checkbox_group',
                'type'  => 'checkbox_group',
                'options' => array (
                    'one' => array (
                        'label' => 'Option One',
                        'value' => 'one'
                    ),
                    'two' => array (
                        'label' => 'Option Two',
                        'value' => 'two'
                    ),
                    'three' => array (
                        'label' => 'Option Three',
                        'value' => 'three'
                    )
                )
            ),
            array(
                'label' => 'Post List',
                'desc'  => 'A description for the field.',
                'id'    =>  $prefix.'post_id',
                'type'  => 'post_list',
                'post_type' => array('post','page')
            ),
        );

        // The Callback
        function home_show_custom_meta_box() {
            global $home_custom_meta_fields, $post;
            // Use nonce for verification
            echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';

            // Begin the field table and loop
            echo '<table class="form-table">';
            foreach ($home_custom_meta_fields as $field) {
                // get value of this field if it exists for this post
                $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>
                        <td>';
                        switch($field['type']) {
                            // text
                            case 'text':
                                echo '<input type="text" name="'.$field['id'].'" id="'.$field['id'].'" value="'.$meta.'" size="30" />
                                        <br /><span class="description">'.$field['desc'].'</span>';
                            break;
                            // textarea
                            case 'textarea':
                                echo '<textarea name="'.$field['id'].'" id="'.$field['id'].'" cols="60" rows="4">'.$meta.'</textarea>
                                        <br /><span class="description">'.$field['desc'].'</span>';
                            break;
                            // checkbox
                            case 'checkbox':
                                echo '<input type="checkbox" name="'.$field['id'].'" id="'.$field['id'].'" ',$meta ? ' checked="checked"' : '','/>
                                        <label for="'.$field['id'].'">'.$field['desc'].'</label>';
                            break;
                            // select
                            case 'select':
                                echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
                                foreach ($field['options'] as $option) {
                                    echo '<option', $meta == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
                                }
                                echo '</select><br /><span class="description">'.$field['desc'].'</span>';
                            break;
                            // radio
                            case 'radio':
                                foreach ( $field['options'] as $option ) {
                                    echo '<input type="radio" name="'.$field['id'].'" id="'.$option['value'].'" value="'.$option['value'].'" ',$meta == $option['value'] ? ' checked="checked"' : '',' />
                                            <label for="'.$option['value'].'">'.$option['label'].'</label><br />';
                                }
                                echo '<span class="description">'.$field['desc'].'</span>';
                            break;
                            // checkbox_group
                            case 'checkbox_group':
                                foreach ($field['options'] as $option) {
                                    echo '<input type="checkbox" value="'.$option['value'].'" name="'.$field['id'].'[]" id="'.$option['value'].'"',$meta && in_array($option['value'], $meta) ? ' checked="checked"' : '',' /> 
                                            <label for="'.$option['value'].'">'.$option['label'].'</label><br />';
                                }
                                echo '<span class="description">'.$field['desc'].'</span>';
                            break;
                            // tax_select
                            case 'tax_select':
                                echo '<select name="'.$field['id'].'" id="'.$field['id'].'">
                                        <option value="">Select One</option>'; // Select One
                                $terms = get_terms($field['id'], 'get=all');
                                $selected = wp_get_object_terms($post->ID, $field['id']);
                                foreach ($terms as $term) {
                                    if (!empty($selected) && !strcmp($term->slug, $selected[0]->slug)) 
                                        echo '<option value="'.$term->slug.'" selected="selected">'.$term->name.'</option>'; 
                                    else
                                        echo '<option value="'.$term->slug.'">'.$term->name.'</option>'; 
                                }
                                $taxonomy = get_taxonomy($field['id']);
                                echo '</select><br /><span class="description"><a href="'.get_bloginfo('home').'/wp-admin/edit-tags.php?taxonomy='.$field['id'].'">Manage '.$taxonomy->label.'</a></span>';
                            break;
                            // post_list
                            case 'post_list':
                            $items = get_posts( array (
                                'post_type' => $field['post_type'],
                                'posts_per_page' => -1
                            ));
                                echo '<select name="'.$field['id'].'" id="'.$field['id'].'">
                                        <option value="">Select One</option>'; // Select One
                                    foreach($items as $item) {
                                        echo '<option value="'.$item->ID.'"',$meta == $item->ID ? ' selected="selected"' : '','>'.$item->post_type.': '.$item->post_title.'</option>';
                                    } // end foreach
                                echo '</select><br /><span class="description">'.$field['desc'].'</span>';
                            break;
                            // date
                            case 'date':
                                echo '<input type="text" class="datepicker" name="'.$field['id'].'" id="'.$field['id'].'" value="'.$meta.'" size="30" />
                                        <br /><span class="description">'.$field['desc'].'</span>';
                            break;
                            // slider
                            case 'slider':
                            $value = $meta != '' ? $meta : '0';
                                echo '<div id="'.$field['id'].'-slider"></div>
                                        <input type="text" name="'.$field['id'].'" id="'.$field['id'].'" value="'.$value.'" size="5" />
                                        <br /><span class="description">'.$field['desc'].'</span>';
                            break;
                            // image
                            case 'image':
                                $image = get_template_directory_uri().'/images/image.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" alt="" /><br />
                                                <input class="custom_upload_image_button button" type="button" value="Choose Image" />
                                                <small>&nbsp;<a href="#" class="custom_clear_image_button">Remove Image</a></small>
                                                <br clear="all" /><span class="description">'.$field['desc'].'</span>';
                            break;
                            // repeatable
                            case 'repeatable':
                                echo '<a class="repeatable-add button" href="#">+</a>
                                        <ul id="'.$field['id'].'-repeatable" class="custom_repeatable">';
                                $i = 0;
                                if ($meta) {
                                    foreach($meta as $row) {
                                        echo '<li><span class="sort hndle">|||</span>
                                                    <input type="text" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="'.$row.'" size="30" />
                                                    <a class="repeatable-remove button" href="#">-</a></li>';
                                        $i++;
                                    }
                                } else {
                                    echo '<li><span class="sort hndle">|||</span>
                                                <input type="text" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="" size="30" />
                                                <a class="repeatable-remove button" href="#">-</a></li>';
                                }
                                echo '</ul>
                                    <span class="description">'.$field['desc'].'</span>';
                            break;
                        } //end switch
                echo '</td></tr>';
            } // end foreach
            echo '</table>'; // end table
        }

        // Save the Data
        function home_save_custom_meta($post_id) {
            global $home_custom_meta_fields;

            // verify nonce
            if (!wp_verify_nonce($_POST['custom_meta_box_nonce'], basename(__FILE__))) 
                return $post_id;
            // 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_custom_meta_fields as $field) {
                $old = get_post_meta($post_id, $field['id'], true);
                $new = $_POST[$field['id']];
                if ($new && $new != $old) {
                    update_post_meta($post_id, $field['id'], $new);
                } elseif ('' == $new && $old) {
                    delete_post_meta($post_id, $field['id'], $old);
                }
            } // enf foreach
        }
        add_action('save_post', 'home_save_custom_meta');

        }

Here's how I've wrapped all categories into a array:

            // Get all categories from WP and create a dropdown
        $categories = get_categories('hide_empty=0&orderby=name');
        $wp_cats = array();
        foreach ($categories as $category_list ) {
               $wp_cats[$category_list->cat_ID] = $category_list->cat_name;
        }
        array_unshift($wp_cats, "Choose a category"); 
share|improve this question

1 Answer 1

The problem was in how the the categories were stored in the array that didn't go with the meta box code. To resolve the issue I've used a function (kindly provided by Jonathan Kuhn) that wrapped the categories in a way that I could use with the mate box code. Here's the function:

// Wrap all categories in a function
function wcat2() {
    $out = array();
    $categories = get_categories();
    foreach( $categories as $category ) {
        $out[$category->term_id] = array(
            'label' => $category->slug,
            'value' => $category->term_id
        );
    }
    //return array('options'=>$out);
    return $out;
}

This function should replace this code:

 // Get all categories from WP and create a dropdown
    $categories = get_categories('hide_empty=0&orderby=name');
    $wp_cats = array();
    foreach ($categories as $category_list ) {
           $wp_cats[$category_list->cat_ID] = $category_list->cat_name;
    }
    array_unshift($wp_cats, "Choose a category");

Now all you have to do is call the function from the array in meta box:

    array(
            'label' => 'Category',
            'id'    => $prefix.'category',
            'type'  => 'select',
            'options' => wcat2()
        ),

This way you can have a meta box that will drawn all used categories from WordPress so the user can select the category from the meta box option as opposed to have to write the category name.

share|improve this answer

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.