Custom Meta Boxes: Armazena dois valores em um campo repetitivo

4

Estou tentando criar uma caixa meta personalizada em que o usuário pode adicionar campos conforme necessário. Eu segui este tutorial: enlace

Eu gostaria de expandir este tutorial e criar um campo repetível que permita duas entradas. Por exemplo: nome e URL.

Como eu poderia conseguir isso?

Eu encontrei esta outra pergunta aqui: Crie mais Meta Boxes conforme necessário

Consegui integrar o exemplo da caixa meta ao meu tipo de postagem personalizado, mas não consegui descobrir como enviar os meta-valores para o meu tema. Aqui o código com o qual estou trabalhando:

    /*---------------------------*/
    /* 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 o código acima, sou capaz de gerar a caixa meta dinâmica na tela de edição do CPT e salvar dados nos campos com êxito.

Estou um pouco envergonhado de admitir, mas não sei como exibir as informações desses campos no meu tema. Consegui exibir com êxito outras informações meta personalizadas armazenadas em outros campos usando

<?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>';
?>

Qualquer ajuda seria muito apreciada!

    
por derekshirk 17.05.2012 / 00:47

1 resposta

2

O array serializado que as caixas meta salvam está deformado. Fiz algumas pequenas alterações no seu código para que ele funcionasse. Eu criei um novo post e aqui está o que foi salvo depois de ser desserializado.

Nota: o WordPress irá desserializar automaticamente um array armazenado em post_meta. Use um semializante on-line se quiser verificar o conteúdo.

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 produzir isso no front-end, você apenas chama get_post_meta () e percorre o array.

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

No front-end, isso nos dá uma boa lista não ordenada com a faixa e o título:

  • Voltar em preto - 1
  • Hells Bells - 2
  • Quente para o professor - 3
  • Cadela da Cidade do Rack - 4

Alterações no código:

Eu tive que mudar seu campo de página para post em suas definições de meta box para que ele carregasse em um post e também movi-as para dentro da função add_meta_box para que não tivéssemos que lidar com torná-las globais. Na sua função de show box eu conjurei a variável get_post_meta em um array para me livrar do argumento inválido fornecido para o erro foreach que eu obtive no Xdebug e consertei seu 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++;
                }
            }
        }
    
por Chris_O 17.05.2012 / 08:23