web-dev-qa-db-fra.com

Méta-boîtes personnalisées: stockez deux valeurs dans un même champ répétable

J'essaie de créer une méta-boîte personnalisée dans laquelle l'utilisateur peut ajouter des champs si nécessaire. J'ai suivi ce tutoriel: http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-1-intro-and-basic-fields/

Je voudrais développer ce tutoriel et créer un champ répétable qui permet deux entrées. Par exemple: Nom et URL.

Comment pourrais-je y parvenir?

J'ai trouvé cette autre question ici: Créer plus de boîtes de méta au besoin

J'ai pu intégrer l'exemple de méta-boîte à mon type d'article personnalisé, mais je ne savais pas comment afficher les méta-valeurs dans mon thème. Voici le code avec lequel je travaille:

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

Utilisation du code ci-dessus, je suis capable de générer la méta-boîte dynamique sur mon écran d'édition CPT et de sauvegarder les données dans les champs avec succès.

Je suis un peu gêné de l'admettre, mais je ne sais pas comment afficher les informations de ces champs dans mon thème. J'ai réussi à afficher d'autres métadonnées personnalisées stockées dans d'autres champs à l'aide de

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

Toute aide serait grandement appréciée!

4
derekshirk

Le tableau sérialisé que vos méta-boîtes enregistrent est déformé. J'ai apporté quelques légères modifications à votre code pour le faire fonctionner. J'ai créé un nouveau message et voici ce qui a été enregistré après avoir été désérialisé.

Remarque: WordPress désérialisera automatiquement un tableau stocké dans post_meta. Utilisez un désosseur en ligne si vous souhaitez vérifier le contenu.

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
) 
)

Pour sortir ceci au début, appelez simplement get_post_meta () et passez en boucle dans le tableau.

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

Sur le front-end, cela nous donne une liste non ordonnée de Nice avec la piste et le titre:

  • Retour en noir - 1
  • Hells Bells - 2
  • Chaud pour l'enseignant - 3
  • Rack ville chienne - 4

Changements de code:

Je devais changer votre champ de page en post dans vos définitions de méta-boîtes pour le charger sur un message. Je les ai également déplacées à l'intérieur de la fonction add_meta_box pour que nous n'ayons pas à nous soucier de les rendre globales. Dans votre fonction show box, j'ai converti la variable get_post_meta dans un tableau afin de supprimer l'argument non valide fourni pour l'erreur foreach que j'ai eu dans Xdebug et de corriger votre compteur.

$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++;
                }
            }
        }
2
Chris_O