Meta cajas personalizadas: almacene dos valores en un campo repetible

4

Estoy intentando crear un meta box personalizado donde el usuario puede agregar campos según sea necesario. Seguí este tutorial: enlace

Me gustaría ampliar este tutorial y crear un campo repetible que permita dos entradas. Por ejemplo: Nombre y URL.

¿Cómo podría lograr esto?

Encontré esta otra pregunta aquí: Cree más Meta Boxes según sea necesario

Pude integrar el ejemplo de meta box en mi tipo de publicación personalizada, pero no pude averiguar cómo generar los meta valores en mi tema. Aquí el código con el que estoy trabajando:

    /*---------------------------*/
    /* Define Metabox Fields
    /*---------------------------*/

    $prefix = 'tz_';

    $custom_downloads = array(
         'id' => 'custom-downloads',
         'title' => __('Custom Downloads Downloads (Beta)'),
         'page' => 'categories-supported',
         'context' => 'normal',
         'priority' => 'high',
         'fields' => array(

        array(
            'name' => __('Add Product Downloads', 'framework'),
            'desc' => __('This meta box is under development', 'framework'),
            'id' => $prefix . 'custom-downloads',
            'type' => 'text',
            'std' => ''
        ),                        
      )
    );

    /*-------------------------------------*/
    /* Add Meta Box to CPT screen 
    /*-------------------------------------*/

    function tz_add_box() {
        global $custom_downloads;

        add_meta_box($custom_downloads['id'], $custom_downloads['title'], 'tz_show_box_custom_dwnld', $custom_downloads['page'], $custom_downloads['context'], $custom_downloads['priority']);


    }

 }

 add_action('admin_menu', 'tz_add_box');

    /*------------------------------------------*/
    /* Callback function/show fields in meta box
    This is taken directly from: https://wordpress.stackexchange.com/questions/19838/create-more-meta-boxes-as-needed
    /*------------------------------------------*/


    function tz_show_box_custom_dwnld() {
        global $custom_downloads, $post;
        // Use nonce for verification
        echo '<input type="hidden" name="tz_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';


        ?>
        <div id="meta_inner">
        <?php

        //get the saved meta as an arry
        $songs = get_post_meta($post->ID,'songs',true);

        $c = 0;
        if ( count( $songs ) > 0 ) {
            foreach( $songs as $track ) {
                if ( isset( $track['title'] ) || isset( $track['track'] ) ) {
                    printf( '<p>Song Title <input type="text" name="songs[%1$s][title]" value="%2$s" /> -- Track number : <input type="text" name="songs[%1$s][track]" value="%3$s" /><span class="remove">%4$s</span></p>', $c, $track['title'], $track['track'], __( 'Remove Track' ) );
                    $c = $c +1;
                }
            }
        }

        ?>
        <span id="here"></span>
        <span class="add"><?php _e('Add Tracks'); ?></span>
        <script>
        var $ =jQuery.noConflict();
        $(document).ready(function() {
        var count = <?php echo $c; ?>;
        $(".add").click(function() {
        count = count + 1;

        $('#here').append('<p> Song Title <input type="text" name="songs['+count+'][title]" value="" /> -- Track number : <input type="text" name="songs['+count+'][track]" value="" /><span class="remove">Remove Track</span></p>' );
        return false;
        });
        $(".remove").live('click', function() {
        $(this).parent().remove();
        });
        });
        </script>
        </div>
        <?php

    }

/*-------------------------------------*/
/* Save data when post is edited
/*-------------------------------------*/


function tz_save_data($post_id) {
    global $meta_box, $meta_box_video, $meta_box_video_page, $meta_box_product_tabs, $meta_deployments, $meta_features, $meta_downloads;
    // verify nonce
    if (!wp_verify_nonce($_POST['tz_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;
    }


 $songs = $_POST['songs'];
    update_post_meta($post_id,'songs',$songs);


}

add_action('save_post', 'tz_save_data');

Usando el código anterior, puedo generar el meta box dinámico en mi pantalla de edición de CPT y puedo guardar datos en los campos con éxito.

Me da un poco de vergüenza admitirlo, pero no sé cómo mostrar la información de estos campos en mi tema. He podido mostrar con éxito otra información meta personalizada almacenada en otros campos utilizando

<?php $post_meta_data = get_post_custom($post->ID); ?>
<?php $custom_features = unserialize($post_meta_data['tz_features-repeat'][0]); ?>

<?php echo '<ul class="deployments">';
    foreach ($custom_deployments as $string) {
        echo '<li>'.$string.'</li>';
    }
    echo '</ul>';
?>

Cualquier ayuda sería muy apreciada!

    
pregunta derekshirk 17.05.2012 - 00:47

1 respuesta

2

La matriz serializada que guardan tus meta boxes está deformada. Hice algunos cambios leves en tu código para que funcione. Creé una nueva publicación y aquí está lo que se guardó después de no ser serializado.

Nota: WordPress deserializará automáticamente una matriz almacenada en post_meta. Utilice un unserializer en línea si alguna vez desea consultar el contenido.

Array
(
[1] => Array
(
[title] => Back in Black
[track] => 1
) [2] => Array
(
[title] => Hells Bells
[track] => 2
) [3] => Array
(
[title] => Hot for Teacher
[track] => 3
) [4] => Array
(
[title] => Rack City Bitch
[track] => 4
) 
)

Para mostrar esto en el extremo frontal, simplemente llama a get_post_meta () y recorre la matriz.

add_filter( 'the_content', 'get_your_track_meta' );
    function get_your_track_meta( $content ) {
        global $post;
        $metadata = get_post_meta( $post->ID, 'songs', true );
        $content .= '<ul>';
        foreach ( (array) $metadata as $meta) {
            $content .= '<li>' . $meta['title'] . ' -- ' . $meta['track'] . '</li>';
        }
        $content .= '</ul>';
        return $content;
    }

En la parte delantera, esto nos da una buena lista desordenada con la pista y el título:

  • De vuelta en negro - 1
  • Hells Bells - 2
  • Hot for Teacher - 3
  • Rack City Bitch - 4

Cambios de código:

Tuve que cambiar el campo de tu página a post en tus definiciones de meta box para que se cargara en una publicación y también las moví dentro de la función add_meta_box para que no tuviéramos que tratar de hacerlas globales. En la función de mostrar la caja, lanzo la variable get_post_meta a una matriz para eliminar el argumento no válido proporcionado para el error foreach que obtuve en Xdebug y arreglé su contador.

$songs = get_post_meta( $post->ID, 'songs', true );
        $c = 0;
        if ( count( $songs ) > 0 ) {
            foreach ( (array)$songs as $track ) {
                if ( isset( $track['title'] ) || isset( $track['track'] ) ) {
                    printf( '<p>Song Title <input type="text" name="songs[%1$s][title]" value="%2$s" /> -- Track number : <input type="text" name="songs[%1$s][track]" value="%3$s" /><span class="remove">%4$s</span></p>', $c, $track['title'], $track['track'], __( 'Remove Track' ) );
                    $c++;
                }
            }
        }
    
respondido por el Chris_O 17.05.2012 - 08:23

Lea otras preguntas en las etiquetas