web-dev-qa-db-ja.com

カスタムメタボックス:1つの繰り返し可能フィールドに2つの値を格納します

ユーザーが必要に応じてフィールドを追加できるカスタムメタボックスを作成しようとしています。私はこのチュートリアルに従った: http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-1-intro-and-basic-fields/

このチュートリアルを拡張して、2つの入力を可能にする反復可能フィールドを作成したいと思います。例:名前とURL。

どうすればこれを達成できますか?

私はここでこの他の質問を見つけました: 必要に応じてもっとメタボックスを作成する

メタボックスの例を自分のカスタム投稿タイプに統合することはできましたが、メタ値を自分のテーマに出力する方法がわかりませんでした。これが私が働いているコードです:

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

上記のコードを使用するCPT編集画面で動的メタボックスを生成し、フィールドにデータを正常に保存することができます。

私はそれを認めるのは少し恥ずかしいですが、私は私のテーマでこれらのフィールドからの情報を表示する方法がわかりません。を使用して、他のフィールドに格納されている他のカスタムメタ情報を正常に表示することができました

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

任意の助けは大歓迎です!

4
derekshirk

メタボックスが保存しているシリアル化された配列は変形しています。動作させるために、コードに若干の変更を加えました。私は新しい投稿を作成しました。これは、シリアル化解除された後に保存されたものです。

注: WordPressはpost_metaに格納されている配列を自動的にシリアル化解除します。内容を確認したい場合は、 online unserializer を使用してください。

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

これをフロントエンドに出力するには、get_post_meta()を呼び出して配列をループ処理するだけです。

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

フロントエンドではこれは私たちにトラックとタイトルを付けたニース順不同リストを与える:

  • 黒に戻る - 1
  • ヘルズベルズ - 2
  • 教師のためのホット - 3
  • ラックシティービッチ - 4

コードの変更

私はあなたのメタボックス定義であなたのページフィールドをpostに変更して投稿にロードするようにしなければなりませんでした、そしてそれらをadd_meta_box関数の中に移動してグローバルにする必要はありません。あなたのショーボックス関数で、私はXdebugで得たforeachエラーのために供給された無効な引数を取り除くためにget_post_meta変数を配列にキャストしてあなたのカウンターを修正しました。

$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