【WordPress】カスタムフィールドをfunctions.phpで自作する

あまりプラグインを増やさないで、カスタム投稿やカスタムフィールドを実装したいという記事の2つ目です。

前回カスタム投稿タイプとカスタムタクソノミーをfunctions.phpで自作したので、今回はカスタムフィールドをやります。

自分で使うものだから

普段なら「Advanced Custom Fields」(以下「ACF」)にお世話になるカスタムフィールドの作成なのですが。

今回は自分だけが使用するブログということもあり、勉強がてらやってみることにしました。

「ACF」は便利は便利なんですけど、利用目的が決まっていることを考えるとそんなに高機能じゃなくても良いなと。

あとは、使用しているテーマがあまり重たくならないように・・・

UIとかを考えたら、CSSが苦手な自分としては絶対「ACF」なんですけどね。

ただ、値の取り回しなど色々とコードをいじる事になりそうだったので。

であればコードを色々調べるよりも、最初から分かってる方が良いなというのも自作することにした理由です。

まずは編集画面でのカスタムフィールドを定義

最初にワードプレス関数のadd_meta_box()を利用し、編集画面に表示されるオリジナルのカスタムフィールドを定義します。

ブロックエディタだと、本文の編集欄の下に表示されるセクションの一つですね。

function create_customfields(){
    add_meta_box(
        'test_fields',          //セクションのID
        'テストカスタムフィールド',    //セクションのタイトル
        'test_fields_form',    //フォーム部分を指定する関数
        'test_type',           //投稿タイプ
        'normal',               //セクションの表示場所
        'default'               //優先度
    );
}
add_action( 'admin_menu', 'create_customfields' );

まず、セクションのIDを決めます。カスタムフィールドのセクションのHTMLでのIDなので、半角英数で。

そして、セクションのタイトルを決めます。表示名なので、日本語でOKです。

実際のカスタムフィールドは関数に定義して呼び出す流れなので、ここに関数名を指定します。関数を先に作っても、ここで関数名だけ決めてもどちらでも良いかと。

次にこのカスタムフィールドを表示する投稿タイプを指定します。今回はカスタム投稿タイプで使用したいので、カスタム投稿タイプ名を入力しました。

通常の投稿であればpost、固定ページであればpageを指定しましょう。

セクションの表示位置は’normal’に。サイドバーに表示したい場合はsideを。

最期の表示の優先度は’default’を指定しました。

そして、admin_menuのアクションフックを使います。

各引数について詳しくは、リファレンスをご覧いただくのが良いかと。

カスタムフィールドは3段階

カスタムフィールドは、

・保存されている値を呼び出す
・値を入力するフィールドを作る
・入力した値を保存する

の3段階で作成します。

編集するフィールドなので、入力されている値があれば表示してほしいし、入力欄がどれか分かりやすくしてほしいし、入力した値を保存して欲しいですからね。

ざっくりとこんな感じです。

<?php
//フォーム作成
function test_fields_form( $post ){
    //nonceフィールドの追加
    wp_nonce_field( 'custom_field_save_meta_box_data', 'custom_field_meta_box_nonce' );

    //保存済データの取得
    $test_field_value = get_post_meta( $post->ID, 'test_text_field', true );
?>

<!--フォーム表示の設定-->
<label for="test_text">武将名</label>
        <input id="test_text" name="test_text_field" type="text" value="<?php echo $test_field_value; ?>" >

<?php
}
//データの保存処理
function save_custom_fields( $post_id ){
    //nonceチェック
    if( !isset( $_POST['custom_field_meta_box_nonce'] ) ){
        return;
    }

    //nonceの検証
    if( !wp_verify_nonce( $_POST['custom_field_meta_box_nonce'], 'custom_field_save_meta_box_data' ) ){
        return;
    }

    //データ保存
    //武将情報
    if( isset($_POST['test_text_field'] ) ){
        $data = sanitize_text_field( $_POST['test_text_field'] );
        update_post_meta( $post_id, 'test_text_field', $data );
    }
}
add_action( 'save_post', 'save_custom_fields' );
?>

保存済みデータの取得

まずはカスタムフィールドに保存されている値の取得を、get_post_meta()で行います。

基本的にプログラムは上から順に読まれるので、最初に保存されている値を呼び出さないと、フィールドに表示できません。

//保存済データの取得
    $test_field_value = get_post_meta( $post->ID, 'test_text_field', true );
?>

get_postmeta( 'カスタムフィールドの投稿ID’, '取得するカスタム投稿のフィールドキー’, '単一の値を返すかどうか’ )なので。

$post->IDで現在の投稿IDを指定し、’test_text_field’というカスタムフィールドの、値を返してもらうのでtrue、といった感じです。

その値を変数$test_field_valueに入れておきます。

フィールドをHTMLで作成

次に、取得した値を表示したり、入力するフィールドをHTMLで作ります。

入力フォームといえば<input>。

<!--フォーム表示の設定-->
<label for="test_text">テキストフィールド</label>
        <input id="test_text" name="test_text_field" type="text" value="<?php echo $test_field_value; ?>" >

name属性をget_post_meta()の第2引数で指定したものと同じ名前にします。

$test_field_valueをvalue値でecoし、取得したカスタムフィールドの値を表示させています。

フォームが複数ある場合入力欄だけだと何が何やら・・・となってしまうので、<label>をしっかり入れておきました。

ここまでが、add_meta_box()で指定した関数の動作範囲です。

保存する

カスタムフィールドの値は投稿と共に保存されるように、save_postアクションフックを利用します。

なので、さきほどまでとは別の関数を定義します。

カスタムフィールドの値を保存・更新するのは、update_post_meta()です。

//データ保存
    if( isset($_POST['test_text_field'] ) ){
        $data = sanitize_text_field( $_POST['test_text_field'] );
        update_post_meta( $post_id, 'test_text_field', $data );
    }
}
add_action( 'save_post', 'save_custom_fields' );
?>

投稿時に保存されるデータはPOST送信されるので、$_POST['HTMLのname属性’]で受け取ります。

まず、安全のために値が存在するかをisset()で確認し、sanitize_text_field()でサニタイズ処理。

update_post_meta( '保存する投稿ID’, '保存するフィールド名’, '保存する値’ )と、第3引数で保存するデータを指定するので、サニタイズ処理をしておくと安心。

そして、save_postにフックすればカスタムフィールド編集の一連の流れができるようになります。

nonceもしっかり

個人使用なのでどうしようかとも思いましたが、もしものために備えてnonceも設定しています。

nonceは1回限りのデータをランダム作成し、安全性を高めるもの。

nonceを送信し、検証するという流れなので。フィールドの作成関数でnonceフィールドを作成し。

//nonceフィールドの追加
    wp_nonce_field( 'custom_field_save_meta_box_data', 'custom_field_meta_box_nonce' );

値を保存する時にnonceがあるかのチェックと検証をします。

//nonceチェック
    if( !isset( $_POST['custom_field_meta_box_nonce'] ) ){
        return;
    }

    //nonceの検証
    if( !wp_verify_nonce( $_POST['custom_field_meta_box_nonce'], 'custom_field_save_meta_box_data' ) ){
        return;
    }

この記事作成時点では見つけられませんでしたが、リファレンスでも「nonceを忘れずにね!」と(こんなフランクかどうかは定かではありませんが)書いてあったので。

忘れずに入力しましょう。

カスタムフィールドも自作できた!

ここまでのコードをfunctions.phpに入力することで、カスタムフィールドを表示できるようになります。

カスタム投稿タイプを利用するほとんどの場合、カスタムフィールドとセットだと思うので一緒に覚えておくことにします。

・・・忘れないように記事にしたんですがw

ただ、このままだと入力ボックスが編集画面に追加されているだけなので、非常に見にくいです。

CSSなどをお好みで調整し、自分だけの編集画面を作りましょう。

(自分はwidth100%に逃げましたw)

参考:プラグインなしでカスタムフィールドを追加する方法【functions.php記述方法の完全版】‐Miyachi Labo