web-dev-qa-db-ja.com

カスタムメタボックスを値の配列として表示/追加/保存する方法を教えてください。

私がやろうとしているのは、カスタム投稿タイプ、その値を 'colors'または 'p_clrs'の配列に挿入するカスタムメタボックスを作成することです。

私はあなたが "デフォルトでは少なくとも1色メタボックスを表示しなければならない"を表示するものの下に別の入力フィールドを追加する "Add Another Color"へのリンクをクリックできるjQueryスクリプトを持っています。 jQueryが追加した入力フィールドは、追加しようとしているそれぞれの値を、私が作成しようとしている「色」の配列の中の別の「色」として格納する必要があります。

Newpostページまたは既存の投稿の編集ページでは、colorsメタボックスはforeachループを実行して、 'p_clrs'変数に存在するメタボックスforeach 'color'を作成する必要があります。

私は配列、マルチ配列、特にforeachループについてはまったく得意ではありません。私はforeachのループが大嫌いです。

タクソノミーを使ってすべてをやり直すことはしたくありません。そして、ここで作成しようとしている配列の各色のループを回避するためにこれを取得すると、できるようになります。私がこのものでする必要がある他の何かを処理するために。私は私がここで立ち往生している配列/ foreachのこぶを乗り越えることができないだけです。

これは私のカスタム投稿タイプの私の商品クラスです。

これは私が投稿情報のためのすべての値を持っているものです(コードがそれらのためにここに含まれていない私の他のメタボックスを含みます)。

class TypeProducts {

    public $prod_meta_fields = array( 
    'title', 'description', 'product_type', 'post_tag',
    'p_sku', 'p_price', 'p_discnt_price', 
    'p_weight', 'p_size_w', 'p_size_h', 
    'p_clrs'
);

これは私のregister_post_type()とregister_taxonomy()のコードも持っているメソッドですが、これは実際には必要ないので省略しました。 register_ptypeと_tax()関数が呼び出された後、initとstuffに追加する必要があるものに対するアクションを追加します。

public function TypeProducts() {
    add_action( 'admin_init', array( &$this, 'product_meta_boxes' ));
    add_action( 'wp_insert_post', array( &$this, 'wp_insert_post' ), 10, 2 );
}

このメソッドは、各投稿フォームフィールドのすべての情報の挿入を行います。これは私のすべてのカスタムメタボックスに対しても機能します。* [別の色を追加]リンク/ボタンをクリックしたときにjQueryによって追加される追加の入力フィールドを除きます。

public function wp_insert_post($post_id, $post = null) {
    if ($post->post_type == 'product') { // my custom post type is 'product'
        foreach ($this->prod_meta_fields as $key) { // loops over the $prod_meta_fields
            $value = @$_POST[$key];
            if (empty($value)) {
                delete_post_meta($post_id, $key);
                continue;
            }
            if (!is_array($value)) {
                if (!update_post_meta($post_id, $key, $value)) {
                    add_post_meta($post_id, $key, $value);
                }
            } else {
                delete_post_meta($post_id, $key);
                foreach ($value as $entry) add_post_meta($post_id, $key, $entry);
            }
        }
    }
}

これが私のメタボックスを追加する方法です。この中でforeachを実行できるかどうかわからない場合は、$ p_clrs値の配列をループして、存在するメタボックスforeach色を追加します(複数ある場合)。それ以外の場合は、表示されるメタボックスは1つだけです(常に少なくとも1つあるはずです)。

    function product_meta_boxes() {
    add_meta_box( 'products-price', 'Product SKU# & Price', array( &$this, 'prod_price_box' ), 'product', 'side', 'high' );
    add_meta_box( 'products-colors', 'Product Colors', array( &$this, 'prod_colors_box' ), 'product', 'normal', 'high' );
    }

メタボックス自体を出力するための私の方法と、追加されたボックスが空でない場合に投稿を保存すると「メタボックス」になる可能性がある追加の入力フィールドを追加および削除するjQueryスクリプトもあります。

これは、私が話していることについてのアイデアをあなたに提供するという意味の写真です。 metabox

現在、最初の入力は、存在する場合は格納されている任意の値でページロードに表示されます。 「別を追加」リンクをクリックすると、同じ値を持つ別の入力が追加されますが、任意の入力フィールドに別の値を保存すると、値を持つ最後の入力の値が保存されます。また、保存時にページをリロードしたときに表示される入力は1つだけです。そこにあったそれぞれの追加された値の入力を表示する必要があります。それは、存在するそれぞれの 'p_clrs'値に対してそのために 'p_clrs'変数/配列にも挿入する必要があります。もう忘れましたか?

    public function prod_colors_box() {
            global $post, $p_clr;
    $p_clr = array();
            $p_clrs = get_post_meta( $post->ID, 'p_clr', true );
    ?>

    <div id="p_colors">
        <p>
            <label for="p_clr_1">
            <strong>Color:</strong> <input id="p_clr_1" name="p_clr" value="<?php echo $p_clrs; ?>" />
            </label>
        </p>
    </div>
        <h4><a href="#" id="addClr">Add Another Color</a></h4>

    <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
    <script type="text/javascript">
    $(function() {

        var clrDiv = $('#p_colors');
        var j = $('#p_colors p').size() + 1;

        $('#addClr').live('click', function() {
            $('<p><label for="p_clr_' + j + '"><strong>Color:</strong> <input id="p_clr_' + j + '" name="p_clr" size="20" value="<?php echo $p_clrs; ?>" /></label> <a href="#" id="remClr">Remove</a></p>').appendTo(clrDiv);
            j++;
            return false;
        });
        $('#remClr').live('click', function() { 
            if( j > 2 ) {
                $(this).parents('p').remove(); 
                j--;
            } return false; 
        });
    });
    </script>

<?php
}

} // end of TypeProducts{} Class

誰かが私にくれることができるどんな助けでもありがとう、そして、これがポストの少し狂っているならば申し訳ありません。このテキストエリアにコードをカットアンドペーストするのは大変でした。私にとってはすごいことでした。

自分がやろうとしていること、あるいはやらなければならないことについての私の説明が完全に明確ではないかどうかも教えてください。ある種の視覚的な表現がないと簡単に説明するのは難しいです。

1
jaredwilli

生成された入力フィールドのname属性をp_clrからp_clr[]に変更するだけです。 $_POST['p_clr']はすべての入力フィールドの値を持つ配列になります。

public function prod_colors_box() {
        global $post, $p_clr;
$p_clr = array();
        $p_clrs = get_post_meta( $post->ID, 'p_clr' );
?>

<div id="p_colors">
    <?php foreach( $p_clrs as $key => $p_clr ) { ?>
    <p>
        <label for="p_clr_<?php echo $key; ?>">
        <strong>Color:</strong> <input id="p_clr_<?php echo $key; ?>" name="p_clr[]" value="<?php echo $p_clr; ?>" />
        </label>
    </p>
    <?php } ?>
</div>
    <h4><a href="#" id="addClr">Add Another Color</a></h4>

<script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
<script type="text/javascript">
$(function() {

    var clrDiv = $('#p_colors');
    var j = $('#p_colors p').size() + 1;

    $('#addClr').live('click', function() {
        $('<p><label for="p_clr_' + j + '"><strong>Color:</strong> <input id="p_clr_' + j + '" name="p_clr[]" size="20" value="<?php echo $p_clrs; ?>" /></label> <a href="#" id="remClr">Remove</a></p>').appendTo(clrDiv);
        j++;
        return false;
    });
    $('#remClr').live('click', function() { 
        if( j > 2 ) {
            $(this).parents('p').remove(); 
            j--;
        } return false; 
    });
});
</script>
3
sorich87