Как добавить все категории в массив, извлечь имена категорий и использовать их с пользовательским мета-полем

По сути, мне нужно добавить пользовательские мета-поля на страницы, и одним из этих параметров должен быть список категорий из предыдущих сообщений. Мне удалось добавить метабоксы и обернуть категории в массив, однако должно быть что-то, что мне не хватает, так как на странице отображается только первая буква имени категории. Вот скриншот результата: скриншот проблемы

Я не могу понять, чего мне не хватает. Вот код для метабокса:

            // 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');

        }

Вот как я обернул все категории в массив:

            // 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"); 

Вот что я ожидаю от массива $wp_cats:

'options' => array (
    'one' => array (
        'label' => 'Option One',
        'value' => 'one'
    ),
    'two' => array (
        'label' => 'Option Two',
        'value' => 'two'
    ),
    'three' => array (
        'label' => 'Option Three',
        'value' => 'three'
    )
)

Вот изображение с подробностями: введите здесь описание изображения


person WagnerMatosUK    schedule 05.12.2012    source источник
comment
У меня возникли проблемы с сортировкой вашего кода, чтобы увидеть, что происходит, но похоже, что вы индексируете строку, а не массив. $s='Test'; echo $s['desc']; выводит 'T', потому что он получает первый символ строки (я полагаю, что индекс строки оценивается как int 0, а не вызывает ошибку).   -  person Jon Hulka    schedule 06.12.2012
comment
Но когда я напечатал (print_r) массив (в данном случае это $wp_cats), он дал мне ключ и значение, например Array([0]=›Blog [1]=›Something... вот что меня смущает. Не отметить, что я использовал код, как указано выше // 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"); , и работал нормально.   -  person WagnerMatosUK    schedule 06.12.2012
comment
Я не могу вам сильно помочь, потому что я не знаю, что система (полагаю, WordPress) ожидает от структуры $wp_cats. По моему опыту, всякий раз, когда я сталкиваюсь с подобными вещами, это происходит потому, что я рассматриваю строку как массив. Вам, вероятно, следует поставить тег wordpress на этот вопрос.   -  person Jon Hulka    schedule 06.12.2012
comment
Я ценю помощь в любом случае. Я добавил больше информации в надежде, что кто-то поймет и сможет помочь.   -  person WagnerMatosUK    schedule 06.12.2012


Ответы (1)


Проблема заключалась в том, как категории хранились в массиве, который не соответствовал коду метабокса. Чтобы решить эту проблему, я использовал функцию (любезно предоставленную Джонатаном Куном), которая обертывала категории таким образом, чтобы я мог использовать их с кодом поля сопряжения. Вот функция:

// 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;
}

Эта функция должна заменить этот код:

 // 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");

Теперь все, что вам нужно сделать, это вызвать функцию из массива в метабоксе:

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

Таким образом, у вас может быть мета-поле, которое будет отображать все используемые категории из WordPress, чтобы пользователь мог выбрать категорию из опции мета-поля, а не писать название категории.

person WagnerMatosUK    schedule 06.12.2012