web-dev-qa-db-ja.com

既存の投稿の選択リストをメタボックスに追加し、それをカスタム投稿タイプに割り当てる

私の質問は部分的にこの答えに基づいています: https://wordpress.stackexchange.com/a/5778/27135

Mikeの答えは本当に素晴らしいもので、私のメタボックスをカスタム投稿タイプに含める必要があるまで、解決策はうまくいきました。うまくいくまでコードを変更しようとしましたが、成功しませんでした。また、私はページごとに複数の選択メタボックスを必要としません(Mikeのコードは3を追加します)。

だから私は最初から始め、すべてを取り除きました。データを自分のフォームに保存する必要があるところまで、それはうまくいきます。

私の現在の主な問題は、発行/保存時に現在選択されているオプションタグを保存する方法がわからないことです。どのデータをoptionタグで取得する必要があるのか​​、update_post_meta()に何を入力するのかわかりません。

どのデータを保存する必要があるかをもっと制御できるように、query_posts()を使用して独自のループを作成することも試みました。

以下のコードはMikeのコードを非常に単純化したものです。私の目標はそれが本質的なものだけを含むようにそれを取り除くことでした、皮肉なことに私はそれをあまりにも多く取り除いたにちがいなく、そして何を理解することができません。現在の選択を保存するために追加する必要があるものを知りたいのですが。 :)

add_action( 'add_meta_boxes', 'select_box_add_meta_box' );
add_action( 'save_post', 'select_box_save_postdata' );

// Create the meta box
function select_box_add_meta_box() {
      add_meta_box(
          'select_item',
          'Select Item',
          'select_box_content',
          'custom_post_type'
      );
}

// Create the meta box content
function select_box_content() {
    $static_args = array(
        'post_type' => 'another_custom_post_type', 
        'show_option_none' => 'Choose item'
    );
    $selected_item = get_post_meta($post->ID,'_selected_item', true);
    for($i=0; $i<=2; $i++) {
        $incrementing_args = array(
            'id' => "selected_item_{$i}",
            'name' => 'selected_item[]',
            'selected' => (empty($selected_item[$i]) ? 0 : $selected_item[$i]),
        );
    }   

    wp_dropdown_pages(array_merge($static_args,$incrementing_args));


}

// Save the selection
function select_box_save_postdata($data, $postarr) {    
    update_post_meta($postarr['ID'], '_selected_item', $postarr['selected_item']);
    return $data;
}
2
ragdollpanda

私はこれがあなたが探していたものだと思います。

クラスの使用に戻りました。使用しているものが、select_box_add_meta_box()select_box_content()、および/またはselect_box_save_postdata()という関数名を使用することを決定した他の人のコードと非常に簡単に競合するためです。クラス名WPSE_85107は、この質問に答える他の誰かと競合する可能性があります。もちろん私はあなたの実際のプラグインにもっと良い名前を選ぶことをお勧めしますが少なくとも衝突とは違うものを選んでください。

クラスを使用することで、(通常)が単にフック名と一致することができるような短くて明確なメソッド名を使用することもできます。これはコードを書くことと理解することの両方をとても簡単にIMOにします。 add_action()を使うときはもう少し複雑ですが、学ぶ方法は1回だけです。

add_action( 'add_meta_boxes', 'select_box_add_meta_box' );

vs:

add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );

そしてあなたは'save_post'を誤用していました。 2の後ろに10があるのはそのためで、これは2つのパラメータを必要とします。ここで10は単にデフォルトの優先順位であり、パラメータの数を指定しなければならなかったためだけに必要です。

add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );

save_post()の正しいパラメータは次のとおりです。

function save_post( $post_id, $post )

これに対して:

function select_box_save_postdata($data, $postarr) 

また、save_post()メソッドでは、それが私たちが気にしている投稿タイプであることと、実際に選択された投稿IDを含む$_POST['selected_post']の有効な要素があることを確認するためにテストしました。

add_meta_box()wp_dropdown_pages()などのさまざまな関数に必要なパラメータを確認しやすいように、(疑似)定数とインスタンス変数を作成することにしました。私はあなたがそれをもっと複雑で他の例のように圧倒的だと思ったのではないかと思うのでコメントを加えなかった。

wp_dropdown_pages()には'hierarchical'投稿タイプが必要であることに注意してください。そのため、$post_type=='post'をリ​​ストに追加するには、ここでハックする必要がありました。この例のテストに使用したテストサイトには、投稿タイプが'post''page'しかありません。あなたが望む投稿タイプを得るために$FOR_POST_TYPE$SELECT_POST_TYPEで2行を変更することができるはずです。

あなたが他の言語で動作する必要があるプラグインを作成している場合に備えて、私はラベルに翻訳関数__()を使いました。

私はadmin_init()を使用したので、他のコードは管理者にあるときだけ実行されフロントエンドには実行されません。それは大したことではありませんが、少しずつ役立ちます。

そしてそれはそれについてです。これがコードです:

<?php
/**
 * Plugin Name: @WPSE 85107
 * Description: <a target="_blank" href="http://wordpress.stackexchange.com/q/85107/89">WPSE 85107</a>
 */

class WPSE_85107 {
  var $FOR_POST_TYPE = 'page';
  var $SELECT_POST_TYPE = 'post';
  var $SELECT_POST_LABEL = 'Post';
  var $box_id;
  var $box_label;
  var $field_id;
  var $field_label;
  var $field_name;
  var $meta_key;
  function __construct() {
    add_action( 'admin_init', array( $this, 'admin_init' ) );
  }
  function admin_init() {
    add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
    add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
    $this->meta_key     = "_selected_{$this->SELECT_POST_TYPE}";
    $this->box_id       = "select-{$this->SELECT_POST_TYPE}-metabox";
    $this->field_id     = "selected-{$this->SELECT_POST_TYPE}";
    $this->field_name   = "selected_{$this->SELECT_POST_TYPE}";
    $this->box_label    = __( "Select {$this->SELECT_POST_LABEL}", 'wpse-85107' );
    $this->field_label  = __( "Choose {$this->SELECT_POST_LABEL}", 'wpse-85107' );
  }
  function add_meta_boxes() {
    add_meta_box(
      $this->box_id,
      $this->box_label,
      array( $this, 'select_box' ),
      $this->FOR_POST_TYPE,
      'side'
    );
  }
  function select_box( $post ) {
    $selected_post_id = get_post_meta( $post->ID, $this->meta_key, true );
    global $wp_post_types;
    $save_hierarchical = $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical;
    $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical = true;
    wp_dropdown_pages( array(
      'id' => $this->field_id,
      'name' => $this->field_name,
      'selected' => empty( $selected_post_id ) ? 0 : $selected_post_id,
      'post_type' => $this->SELECT_POST_TYPE,
      'show_option_none' => $this->field_label,
    ));
    $wp_post_types[$this->SELECT_POST_TYPE]->hierarchical = $save_hierarchical;
  }
  function save_post( $post_id, $post ) {
    if ( $post->post_type == $this->FOR_POST_TYPE && isset( $_POST[$this->field_name] ) ) {
      update_post_meta( $post_id, $this->meta_key, $_POST[$this->field_name] );
    }
  }
}
new WPSE_85107();

私はあなたがあなたがそれを理解することができるようにあなたがそれが単純であることを望んだことを知っています、しかしこれはあなたが求めている機能を考えてあなたのプラグインのためにあなたが望むほとんど最低限です。何も少ないとあなたは肉ではなく、太っていなくなります。

私がしなかったのは、あなたが他の人が使うためのプラグインを作成しているなら、私が本当に必須だと思ういくつかの機能を追加することでした。しかし、あなたはそれらの機能について読むことができます ここで

4
MikeSchinkel

save_postアクションはあなたの関数を呼び出して$ dataや$ postarrではなく$ post_idを送ります。

あなたのselect_box_save_postdata関数は唯一のパラメータとして$ post_idを受け取る必要があります。

add_action( 'save_post', 'select_box_save_postdata' );

function select_box_save_postdata( $post_id ) {
    $selected_item = null;

    // your form data is in the $_POST array
    if ( isset( $_POST['selected_item'] ) && $_POST['selected_item'] ) {
        $selected_item = $_POST['selected_item'];
    }

    // then use the $post_id to save your post meta
    update_post_meta( $post_id, '_selected_item', $selected_item );
}

詳細は save_postの codexページを参照してください - /。

1
jevets