WordPressのREST APIにカスタムフィールドがないなら自分で追加すればいいじゃない

シェアする:

この記事をおすすめしたい人

  • WordPressのREST APIにカスタムフィールドを追加したい人
  • つまりオレ

WordPressのREST APIにカスタムフィールドの値を追加します。

僕の目的はNuxt.jsからAPIを参照するためですが、Nuxt.jsに限らずREST APIを利用する場合には役に立つんじゃないかと思います。

仕組みから説明しているので、コピペでちょこちょこっといじってやりたい人は最後の段落だけ読んでください。

カスタムフィールドなんか必要?

人によっては必要ないと思います。

僕は必要でした。 もしかすると僕のチェック項目を見て「え、オレにも必要じゃん…」って思う人もいると思います。

All In One SEO Packのタイトルやディスクリプション

WordPressを使ってる人って、かなり高い確率で「All In One SEO Pack」プラグインを使ってる印象で、あーいや、なんか競合になるプラグインもあるんでしたっけ。

まぁいいや。 どっちみち多分同じです。

SEO意識してる人は記事ごとにAll In One SEO Packの「SEOタイトル」や「SEOディスクリプション」を設定してたりすると思います。

ですがこの「SEOタイトル」「SEOディスクリプション」共にカスタムフィールドに保存されているため、デフォルトではREST APIに含まれていません。

つまり、別のフレームワークからREST APIで記事を取得する場合、破棄されてしまうんです。

WP-PostViewsのPV数

「WP-PostViews」プラグインのPV数とかどうでしょうか。

PV自体を見せたり、PV順で並び替えしたりと、けっこうな頻度で僕は使っていますが、これもカスタムフィールドなのでデフォルトではAPIに出力されません。

その他のカスタムフィールド

自分でカスタムフィールドを設定している場合、そもそもその値が必要だからカスタムフィールドに追加したわけで、これらがロストしてしまうのはAPIを利用する上で大損間違いないでしょう。

REST APIにはカスタムフィールドは含まれない

含まれていないようです。

と言ってもこの辺は「自分で調べたけどよく分からなかった」という人もいそうで、その理由としてREST API公式と思しきサイトがCSSの指定を「assets/styles/style.css」と設定しているため、サブディレクトリへ移動するとCSSが効かなくなるんですね。 そのせいでリファレンス関連がめちゃくちゃ見にくい。

というわけでCSS修正した「投稿」ページです。 ちゃんとcanonicalを公式に設定してあるのでご容赦を…。

こちらのスキーマを見てもらうと分かりますが、カスタムフィールドは含まれていません。

これはREST API側の仕様のようなのでもう割切ってしまって、必要な追加要素があるなら「自分で追加してやればいいじゃない?」スタンスでいきましょう。

REST API公式に要素を追加する仕組みがある

公式からAPIの出力内容を追加する方法が説明されています。

以下、functions.phpに追加していく内容を順番に説明していきます。

アクションフックの追加

まず最初にアクションフックの指定。


add_action( 'rest_api_init', 'XXXXXXXXX' );

「rest_api_init」の部分はフックで割り込む場所の指定なので固定です。 「XXXXXXXXX」はフック内容を定義する関数名で、自分で書くので好きな名前が使えます。 今回は「api_add_fields」にしましょう。


add_action( 'rest_api_init', 'api_add_fields' );

フックする関数を定義

コールバックと呼ばれているんですが、僕は素人過ぎてピンとこないので、この場合はフック内容を定義する関数のことです。

先ほどの「api_add_fields」を使ってこの↓ような形で書きます。


function api_add_fields() {
  register_rest_field( 'XXXXXXXXX',
    'YYYYYYYYY',
     array(
      'get_callback'    => 'ZZZZZZZZZ',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}

「XXXXXXXXX」には投稿タイプ名が入ります。 投稿の場合は「post」、固定ページの場合は「page」。 調べてませんがおそらくカスタム投稿タイプもいけるでしょう。

「YYYYYYYYY」には自分で決める識別子が入ります。 これは2箇所で使われる値で、まず一つ目は出力されるAPIの項目名になります。 上の例だとこの↓ようにJSONに追加されます。


{
  (略)
  categories: [],
  tags: [],
  YYYYYYYYY: '',
  (略)
}

もうひとつは後で出てきます。

最後に、「ZZZZZZZZZ」の部分はAPIに追加する値を決定する関数名を指定します。 自分で関数を用意するのでここも好きに決められます。 今回は「register_fields」にしましょう。


function api_add_fields() {
  register_rest_field( 'post',
    'YYYYYYYYY',
     array(
      'get_callback'    => 'register_fields',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}

APIに編集機能を持たせる場合は「update_callback」に関数名を指定するようです。

APIに値を追加する関数を定義

先ほどの名前で関数を作ります。


function register_fields( $post, $name, $request, $post_type ) {
  (略)
  return '追加する値'
}

引数がどうなってんのか分からなかったんですが、こちらのユーザからのコメントによると、

  • 「$post」対象のオブジェクト(投稿ならWP_Post)
  • 「$name」先ほどのYYYYYYYYYの文字列
  • 「$request」WP_REST_Request
  • 「$post_type」投稿タイプ(先ほどのXXXXXXXXX)

注意点として、引数の$postはいつものWP_Postオブジェクトではなく、連想配列になっています。 さらに「ID」が小文字の「id」に変わっているので、記事の投稿IDを取得する場合は「$post[ 'id' ]」になります。

3番目のWP_REST_Requestは僕レベルでは何に使うのか分からないし、post_typeは自分で指定しているので既知だしそもそもWP_Postの中に入ってるので、今回この2つは無視します。

この関数で返した値がJSONのYYYYYYYYYの値に入ります。

このまま実行するとこんな↓感じ。


{
  (略)
  categories: [],
  tags: [],
  YYYYYYYYY: '追加する値',
  (略)
}

コールバックの引数を利用して簡単にカスタムフィールドを追加

APIに追加する値を決定する関数の引数に、項目名を受け取れることから、簡単にカスタムフィールドをAPIに追加することができます。


add_action( 'rest_api_init', 'api_add_fields' );
function api_add_fields() {
  register_rest_field( 'post',
    'YYYYYYYYY',
     array(
      'get_callback'    => 'register_fields',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}
function register_fields( $post, $name ) {
  return get_post_meta( $post[ 'id' ], $name, true );
}

あとは、「YYYYYYYYY」にカスタムフィールド名を入れるだけでAPIにカスタムフィールドが名前もそのまま追加されます。

「All In One SEO Pack」のタイトルの場合だとこう↓。


add_action( 'rest_api_init', 'api_add_fields' );
function api_add_fields() {
  register_rest_field( 'post',
    '_aioseop_title',
     array(
      'get_callback'    => 'register_fields',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}
function register_fields( $post, $name ) {
  return get_post_meta( $post[ 'id' ], $name, true );
}

出力結果はこう↓。


{
  (略)
  categories: [],
  tags: [],
  _aioseop_title: '(SEOタイトル名)',
  (略)
}

複数のカスタムフィールドを追加する場合

「All In One SEO Pack」のタイトルだけじゃなくてディスクリプションも追加したい場合はこう↓。


add_action( 'rest_api_init', 'api_add_fields' );
function api_add_fields() {
  register_rest_field( 'post',
    '_aioseop_title',
     array(
      'get_callback'    => 'register_fields',
      'update_callback' => null,
      'schema'          => null,
    )
  );
  register_rest_field( 'post',
    '_aioseop_description',
     array(
      'get_callback'    => 'register_fields',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}
function register_fields( $post, $name ) {
  return get_post_meta( $post[ 'id' ], $name, true );
}

「$name」で処理内容が変わるので、コールバック関数は使い回せます。

出力結果はこう↓。


{
  (略)
  categories: [],
  tags: [],
  _aioseop_title: '(SEOタイトル名)',
  _aioseop_description: '(SEOディスクリプション)',
  (略)
}

コピペで使えるまとめ

WordPressのREST APIにカスタムフィールドを追加するには以下のコードをfunctions.phpにコピペして、YYYYYYYYYにカスタムフィールド名を入れてください。


add_action( 'rest_api_init', 'api_add_fields' );
function api_add_fields() {
  register_rest_field( 'post',
    'YYYYYYYYY',
     array(
      'get_callback'    => 'register_fields',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}
function register_fields( $post, $name ) {
  return get_post_meta( $post[ 'id' ], $name, true );
}

以上、WordPressからお届けしました!

シェアする: