wordpress 編集画面に独自のカスタムフィールドの入力項目を追加する

2013年6月5日

編集画面に独自の入力項目を追加

以下のような手順で、独自の入力項目を作成する。

  1. メタボックスの作成
    • 記事の編集画面は「メタボックス」と呼ばれる枠で囲んだ項目の組み合わせで構成されている。
    • 独自の入力項目を作成する場合にも、まずは新しいメタボックスを作成する。
  2. ニュー力フィールドの作成
    • メタボックスの中に入力フィールドや注意書きなどを表示する。
    • 入力フィールドは HTML のフォームを利用して表示する。
  3. 入力した情報の保存
    • 最後にフィールドに入力した情報をデータベースに保存する処理を指定する。

この例ではカスタム投稿タイプを使った投稿に以下のようなカスタムフィールドを作成。

  • 投稿タイプ:「works」
  • メタボックス:「作品情報」(ID : works_info)
  • 入力フィールド:「素材」(ID : material)
  • 入力フィールド:「写真クレジット」(ID : photo)

メタボックスと入力フィールドには、それぞれ固有の ID を指定する必要がある。

  • メタボックスの ID は個々のメタボックスを識別する div タグの id 属性値として使用される。
  • 入力フィールドの ID は個々の input 要素などの name 属性値として使用される。
  • name 属性の値(ID)は $_POST[ ‘material’] などの形で利用される。
  • ここで指定した、name 属性の値(ID)は実際のカスタムフィールドの名前と一致する必要はないが、同じでも問題ない。

メタボックスの作成

add_meta_box() で「作品情報」というタイトルのメタボックスを作成するように指定し、add_action(‘add_meta_boxes’, ~) で適用する。

function add_my_box() {
  add_meta_box('works_info', '作品情報', 'works_info_form', 'works', 'normal', 'high');
}
add_action('add_meta_boxes', 'add_my_box');

特定のページにだけメタボックスを追加する方法はこちらを参照。

add_meta_box($id, $title, $callback, $page, $context, $priority, $callback_args )
パラメータ
$id (必須):メタボックスの ID(メタボックスである div タグの id 属性値)
$title (必須):メタボックスのタイトル(画面上に表示される)
$callback (必須): メタボックスの内容を表示する( HTML 出力する)関数名
$page (必須):メタボックスの表示先となるページの種類を指定。 (post, page, link, dashboard, カスタムポストタイプ名)
$context (オプション):編集画面での表示場所 (normal, advanced または side) 。デフォルトは「advanced」
$priority (オプション):ボックスが表示される優先度 (high, core, default, low) 。デフォルトは「default」
$callback_args (オプション):表示用関数のパラメータを指定(省略時はnull)。
戻り値: なし。
利用可能箇所:add_meta_boxes アクション(add_action)で使用

メタボックスに注意書き、入力フィールドの追加

  • 第3パラメータで指定した関数に、注意書きと入力フィールド(フォームの input 要素や textarea 要素など)を追加する。
  • input 要素などの name 属性は、前述した ID を指定する(この ID は入力した情報の保存や取得にも使用する)。
  • 「URL」を入力する場合は、type属性を「url」と指定し、URL以外を入力した場合はエラーメッセージが表示されるようにすることができる(HTML5 の機能)。
//第3パラメータで指定した関数の作成
function works_info_form() {  //「作品情報」メタボックスに表示する内容
  global $post;  //編集中の記事に関するデータを保存
  wp_nonce_field(wp_create_nonce(__FILE__), 'my_nonce');  //CSRF対策の設定(フォームにhiddenフィールドとして追加するためのnonceを「'my_nonce」として設定)
?>
  <div id="works_info">
  <p>作品の情報を以下に入力してください。</p>
  <p><label>素材(必須): 複数ある場合は、半角英字のカンマで区切って入力してください。<br />
    <input type="text" name="material" value="<?php echo esc_html(get_post_meta($post->ID, 'material', true)); ?>"  style="width:80%" />
    </label></p> 
  <p><label>写真クレジット(必須): <br />
    <input type="text" name="photo" value="<?php echo esc_html(get_post_meta($post->ID, 'photo', true)); ?>"  style="width:80%" />
    </label></p>  
  </div>
<?php
}

value=”<?php echo esc_html(get_post_meta($post->ID, ‘material’, true)); ?>”
保存した情報を get_post_meta() で取得し、input 要素の value 属性の値として挿入してデータベースに保存した情報がある場合には、入力フィールドに表示する。

同じキーに複数の値がある場合は最初の値のみを取得(複数の値の指定は難しい)

入力フィールドに textarea 要素を使う場合の注意点

入力フィールドに textarea 要素を使う場合は <textarea></textarea> の間に余分な空白や改行を入れないようにする。

<textarea name="notice" rows="3" style="width:80%;"><?php echo get_post_meta($post->ID, 'notice', true); ?></textarea>

以下のように記述してしまうと、保存(更新)の際に毎回余分な空白が追加されていってしまう。

NG の例

<textarea name="notice" rows="3" style="width:80%;">
    <?php echo get_post_meta($post->ID, 'notice', true); ?>
</textarea>

保存の処理を指定

  • フィールドに入力した情報は、update_post_meta() を利用してカスタムフィールドのデータとしてデータベースに保存する。
  • カスタムフィールドでは、キーと値を対にしてデータを管理するので、入力フィールド(input 要素など)の ID をキーとして、入力した情報を保存するように指定する。
  • 指定した処理は add_action(‘save_post’, ~) で適用する。
function my_box_save($post_id) {
  global $post;  //編集中の記事に関するデータを保存
  $my_nonce = isset($_POST['my_nonce']) ? $_POST['my_nonce'] : null;  //設定したnonce を取得(CSRF対策)
  if(!wp_verify_nonce($my_nonce, wp_create_nonce(__FILE__))) {  //nonce を確認し、値が書き換えられていれば、何もしない(CSRF対策)
    return $post_id;
  }
  if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
  //自動保存ルーチンかどうかチェック。そうだった場合は何もしない(記事の自動保存処理として呼び出された場合の対策)
  if(!current_user_can('edit_post', $post->ID)) { return $post_id; }
  //ユーザーが編集権限を持っていない場合は何もしない。
  if($_POST['post_type'] == 'works'){  //'works' 投稿タイプの場合のみ実行  
  //「material, photo」の入力フィールドに入力された情報を保存&更新するように指定
    update_post_meta($post->ID, 'material', $_POST['material']);
    update_post_meta($post->ID, 'photo', $_POST['photo']);  
  }
}
add_action('save_post', 'my_box_save');

update_post_meta($post->ID, ‘カスタムフィールド名’, $_POST[‘入力フィールドのID’])により、入力された値がカスタムフィールドの値に更新される。

update_post_meta($post_id, $meta_key, $meta_value, $prev_value )
投稿情報のカスタムフィールド情報を更新する。指定した名前のカスタムフィールドがない場合は追加する。
パラメータ
$post_id (必須):投稿ID
$meta_key (必須):カスタムフィールド名
$meta_value (必須): カスタムフィールドの値。$_POST['カスタムフィールドの ID'] で取得できる。
$prev_value(オプション):更新前のカスタムフィールドの値(省略時は'')。同じ名前のカスタムフィールドが複数登録されている場合は、この値によって区別する。
戻り値: カスタムフィールド情報を更新(または追加)できた場合はtrue、更新できなかった場合はfalseを返す。
利用可能箇所:save_post アクション(add_action)で使用

全体のコード

function add_my_box() {
  add_meta_box('works_info', '作品情報', 'works_info_form', 'works', 'normal', 'high');
}
add_action('add_meta_boxes', 'add_my_box');

function works_info_form() {  
  global $post;
  wp_nonce_field(wp_create_nonce(__FILE__), 'my_nonce');
?>
  <div id="works_info">
  <p>作品の情報を以下に入力してください。</p>
  <p><label>素材(必須): 複数ある場合は、半角英字のカンマで区切って入力してください。<br />
    <input type="text" name="material" value="<?php echo esc_html(get_post_meta($post->ID, 'material', true)); ?>"  style="width:80%" />
    </label></p> 
  <p><label>写真クレジット(必須): <br />
    <input type="text" name="photo" value="<?php echo esc_html(get_post_meta($post->ID, 'photo', true)); ?>"  style="width:80%" />
    </label></p>  
  </div>
<?php
}

function my_box_save($post_id) {
  global $post;
  $my_nonce = isset($_POST['my_nonce']) ? $_POST['my_nonce'] : null;
  if(!wp_verify_nonce($my_nonce, wp_create_nonce(__FILE__))) {  
    return $post_id;
  }
  if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
  if(!current_user_can('edit_post', $post->ID)) { return $post_id; }
  if($_POST['post_type'] == 'works'){
    update_post_meta($post->ID, 'material', $_POST['material']);
    update_post_meta($post->ID, 'photo', $_POST['photo']);  
  }
}
add_action('save_post', 'my_box_save');

nonceフィールド

nonceフィールドはフォームの内容が現在のサイトから来たものであり、他のサイトからではないということを認証するために使われる。

  • input の name 属性は $name に設定したものになり、input の value 属性は作成されたnonce の値になる。
  • ポストされた nonce は $_POST[$name]でアクセスできる。
wp_nonce_field($action, $name, $referer, $echo)
投稿情報のカスタムフィールド情報を更新する。指定した名前のカスタムフィールドがない場合は追加する。
パラメータ
$action (オプションだが指定する):アクション名(文字列)(初期値: -1)
$name (オプションだが指定する):Nonce の名前(初期値: "_wpnonce" )*nonce にアクセスするにはこの名前を使う→ $_POST[$name]
$referer (オプション): 認証用のrefereフィールドを設定するか否か(初期値: true)
$echo (オプション):hiddenフィールドをフォームに出力するか否か。falseの場合はPHPの値として返す。(初期値: true)
戻り値:Nonceフィールド
wp_verify_nonce($nonce, $action)
投稿情報のカスタムフィールド情報を更新する。指定した名前のカスタムフィールドがない場合は追加する。
パラメータ
$nonce(必須):認証したいフォーム内で使われた nonce
$action (オプション):nonceを作成したときに指定したアクション名(文字列)(初期値: -1)
戻り値:認証に失敗すれば false、成功すれば「1」または「2」の整数値
1:nonce は過去12時間以内に発行されている
2:nonce は過去12時間~24時間以内に発行されている
wp_create_nonce($action)
パラメータ $action :アクション名(文字列/整数)(初期値: -1)
戻り値:ランダムな値のトークン