投稿画面にカスタムフィールド欄を追加する。その2
201004/01 Category : WEB Tag : php, Wordpress
以前「投稿画面にカスタムフィールド欄を追加する。」で書きましたが、投稿する時に、常に表示される固定のカスタムフィールド欄の追加方法。
以前のやり方で間違ってはいないのですが、クライアントからの要望で複数の入力欄を作っていたところ…微妙に希望通りに動いてくれない事が発覚。
今回したかったのは、例えば中古車屋さんのホームページを作っているとして。
・実際に売っている車の『メーカー』と『年式』をカスタムフィールドで登録。
・商品の中には『メーカー』しかわからない物もあれば、『年式』しかわからない物もある。
・クライアントの担当者はパソコンが苦手な方なので、余計な入力欄や混乱する表示は避けたい。
こんな感じですが、とりあえずカスタムフィールド欄を追加追加追加…。いくつか追加した所で、動作確認としてテスト投稿。すると、『メーカー』にしか入力していないはずなのに、『年式』にも空白が登録される。その上、入力した内容を修正しても、うまく更新されない。どうしたもんかなーと悩んで、ずっとハマっていたのですが、この機会だし、phpを最初から調べながら解読していく事に。以前の記事と重複している点が多々ありますが…見逃してくださいw
※個人的にメモ代わりに書いてます。おかしな文章だったりするかもですが、ご了承くださいー。
まず、一番最初。
/*メーカー*/
add_action('admin_menu', 'my_custom_maker') ;
add_action('save_post', 'custom_save_maker') ;
/*年式*/
add_action('admin_menu', 'my_custom_year') ;
add_action('save_post', 'custom_save_year') ;
他のwordpressの記事を書いているサイトを参考にしていたので、なんとなくはわかるけど、正確な意味は不明。調べた結果、wordpressには『フック』と呼ばれる物があって、wordpressの本体以外のデータ(プラグインや、テーマ内のファンクション?)を、本体内に取り込む物らしい。これを使う事によって、プラグインやテーマで管理画面などを変える事が出来るっぽい。んで、『add_action』というのはフックの中でも『アクション』と呼ばれる物みたい。特定イベント発生時に動作するフック。
プラグイン API – WordPress Codex 日本語版
次に引数は、一つ目が、wordpress内のどのイベントと関連付けさせるかで、『admin_menu』は管理画面の基本構造が配置された後に動作させる。『save_post』は投稿などを作成・更新した時に動作させる。二つ目は、そのイベントが起きた時にどの関数を動作させるか。ここはユーザー定義関数。他と被らない、独自の名前をつける。
これで、WP本体へのフックが完了。次。
/*メーカー*/
function my_custom_maker() {
add_meta_box
('my_custom_maker_area', 'メーカー', 'my_custom_maker_in', 'post', 'advanced' );
}
/*年式*/
function my_custom_year() {
add_meta_box
('my_custom_year_area', '年式', 'my_custom_year_in', 'post', 'advanced' );
}
ここでは、最初に指定したユーザー定義関数がどんな動きをするかを決めます。『function』は、phpでユーザー定義関数を定義する時に使う命令文。『add_meta_box』というのは、投稿画面などに、新しいセクションを追加するための関数。
つまり、投稿画面などが配置された時に、新しいセクションを追加する関数を動かす、と。それぞれの引数は以下を参照。
関数リファレンス/add meta box – WordPress Codex 日本語版
どんな動きをするか決める…と書きましたが、実際に出力される(投稿画面に表示される)関数は別に指定しなければいけないみたい。という事で、次はその実際に出力される関数を定義。
/*メーカー*/
function my_custom_maker_in() {
global $post;
echo '<input
type="hidden"
name="mycustom_maker_name"
id="mycustom_maker_name"
value="' .wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
echo '<label for="MAKER">メーカー</label> ';
echo '<input
type="text"
name="MAKER"
value="'.get_post_meta($post->ID,'MAKER',true).'" size="25" />';
}
/*年式*/
function my_custom_year_in() {
global $post;
echo '<input
type="hidden"
name="mycustom_year_name"
id="mycustom_year_name"
value="' .wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
echo '<label for="YEAR">年式</label> ';
echo '<input
type="text"
name="YEAR"
value="'.get_post_meta($post->ID,'YEAR',true).'" size="25" />';
}
ここはちょっと調べてもよくわからない点が…。英語読めません。。。とりあえず、わかる点だけ。
『function』はさっきと同じ。『global』は、変数$postをグローバル変数として宣言。次の行の『hidden』は、表示しないって事なんですが…隠しフィールドって事なんですね。何かを照合してるっぽいんですが、正確にはよくわからないです。とりあえず、他サイトさん見ても必要って書いてあるので、ほっといて次。
『label』と、『input』の『name』の意味はよく使われる物だと思うのでパス。それぞれ同じ名前(MAKER,YEAR)を指定。『value』は入力フォームの初期値で、ここでは『get_post_meta』という関数が出てきます。これはカスタムフィールド情報を取得する関数。引数は以下。
関数リファレンス/get post meta – WordPress Codex 日本語版
実際に投稿画面に表示される入力欄で、初期値は以前登録した値という事だと思う。次ー。
/*メーカー*/
function custom_save_maker ( $post_id ) {
if ( !wp_verify_nonce( $_POST['mycustom_maker_name'], plugin_basename(__FILE__) )) {
return $post_id;
}
if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id )) return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id )) return $post_id;
}
$my_maker_data = ($_POST['MAKER']);
if (get_post_meta($post_id, $my_maker_data) == "")
add_post_meta($post_id, 'MAKER', $my_maker_data, true);
elseif($my_maker_data !=get_post_meta($post_id, 'MAKER', true))
update_post_meta($post_id, 'MAKER',$my_maker_data);
elseif($my_maker_data=="")
delete_post_meta($post_id, 'MAKER',get_post_meta($post_id,'MAKER',true));
/*年式*/
function custom_save_year ( $post_id ) {
if ( !wp_verify_nonce( $_POST['mycustom_year_name'], plugin_basename(__FILE__) )) {
return $post_id;
}
if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id )) return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id )) return $post_id;
}
$my_year_data = $_POST['YEAR'];
if (get_post_meta($post_id, $my_year_data) == "")
add_post_meta($post_id, 'YEAR', $my_year_data, true);
elseif($my_year_data !=get_post_meta($post_id, 'YEAR', true))
update_post_meta($post_id, 'YEAR',$my_year_data);
elseif($my_year_data=="")
delete_post_meta($post_id, 'YEAR',get_post_meta($post_id,'YEAR',true));
最後。まず、上の方の数行は、あまり情報がなかったのと、英語だったのでスルー。多分実際に投稿された、記事のID絡みじゃないかなーと想像。妄想?
『$my_xxxx_data』から説明。
それぞれの変数に、『input』で入力した値を代入。『=』は代入するって意味。『$_POST』はスーパーグローバル変数だとかいう、すでに定義済みの宣言なしで使える変数。$_POSTはブラウザから入力した情報を代入されるみたい。
次にif文。『if』はそのまんまで、『もしxxxなら』という命令文。一つ目のifは、『get_post_meta』で取得した、登録済みのカスタムフィールドと『”"』が同じなら、『add_post_meta』で、指定したID,キー(MAKERやYEAR)のカスタムフィールドを作成。『==』は、同じなら、という意味。『”"』というのは、多分空白って事でいいんだけど…登録済みの内容が空なら、入力された内容でカスタムフィールドを作成?
二つ目のif文。『elseif』なので、一つ目の条件に当てはまらなかった場合で、代入された変数『$my_xxxx_data』が、登録済みのカスタムフィールドと違ったら、代入された変数をカスタムフィールドに更新するという意味。『!=』は違ったら、という意味。『update_post_meta』という関数なので、指定したID,キーのカスタムフィールドを更新って事でいいはず。後でメーカーや年式を修正したい時とかに必要になる条件。
三つ目のifもelseifで、一つ目の条件にも、二つ目の条件にも当てはまらなかった場合は、代入された変数『$my_xxxx_data』が『”"』だった場合、つまり入力がなかった場合、『delete_post_meta』関数で、指定したカスタムフィールドを削除するという事だと思う。
以上で、自分なりに全文解読したつもり。ここから、一番最初に書いたように、クライアントの要望通りになるように、よくわからないながらもいじった結果、最後のifの部分だけを以下のように変更。
/*メーカー*/
function custom_save_maker ( $post_id ) {
if ( !wp_verify_nonce( $_POST['mycustom_maker_name'], plugin_basename(__FILE__) )) {
return $post_id;
}
if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id )) return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id )) return $post_id;
}
$my_maker_data = ($_POST['MAKER']);
if($my_maker_data != get_post_meta($post_id, 'MAKER', true))
update_post_meta($post_id, 'MAKER', $my_maker_data);
elseif($my_maker_data=="")
delete_post_meta($post_id, 'MAKER',get_post_meta($post_id,'MAKER',true));
/*年式*/
function custom_save_year ( $post_id ) {
if ( !wp_verify_nonce( $_POST['mycustom_maker_name'], plugin_basename(__FILE__) )) {
return $post_id;
}
if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id )) return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id )) return $post_id;
}
$my_year_data = $_POST['YEAR'];
if($my_year_data !=get_post_meta($post_id, 'YEAR', true))
update_post_meta($post_id, 'YEAR',$my_year_data);
elseif($my_year_data == "")
delete_post_meta($post_id, 'YEAR',get_post_meta($post_id,'YEAR',true));
一番上にあったif文を削除して、少し条件を変更。考えてみれば、登録済みのカスタムフィールドが空だった場合、カスタムフィールドを作成。という事は、もし入力されていない場合でも、カスタムフィールドが空だった場合、空っぽの状態でカスタムフィールドが作成されるって事ですもんね…。僕の解釈が間違ってなければw
以上です。もしこのブログを見た方がいて、おかしな部分があった場合、勉強の為にもご指摘頂ければ幸いです…
それにしても、長かったー。。。