WordPressのREST APIで前後の記事を取得する

シェアする:

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

  • WordPressのREST APIで前後の記事を取得したい人
  • つまりオレ

今回はWordPressのREST APIで前後の記事を取得します。

今どきそんなものなくても関連記事やカテゴリから別記事にたどれるので不要かもしれませんが、このサイトはページ末尾に前後の記事への誘導を置いているのでやります。

headの「link rel=prev」とかもあるので、知っておいて損はないんじゃないかなと。

REST API側に前後の記事の情報は含まれていないのか?

仕様を見る感じなさそうです。

実際のJSONの中身見ると、ここにはない「_links」って項目があったので期待したんですが、ありませんでした。

「_links」の中身は次の通り。

  • 「self」
    そのページを取得するAPIクエリ
  • 「collection」
    同じ投稿タイプの一覧を取得するAPIクエリ
  • 「about」
    そのページの投稿タイプを取得するAPIクエリ
  • 「author」
    そのページの著者を取得するAPIクエリ
  • 「replies」
    そのページのコメントを取得するAPIクエリ
  • 「version-history」
    そのページの編集リビジョンを取得するAPIクエリ
  • 「wp:attachment」
    そのページのメディアファイルを取得するAPIクエリ
  • 「wp:term」
    そのページのカテゴリとタグを取得するAPIクエリ
  • 「curies」
    謎(「https://api.w.org/」とか入ってました)

というわけで、今回も自分でAPIに項目を追加していきます。

REST APIへ値を追加する基本

基本は以下のような格好です。


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

XXXXXXXXXの部分にAPIに追加するキーの名前を、YYYYYYYYYの部分でAPIに追加する値を設定します。 その他の部分については以前の記事を見てください。

この場合、JSONは以下のように出力されます。


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

今回は子要素を持つ情報なので、YYYYYYYYYには連想配列を放り込もうと思います。

前後の記事とは言ってもAPIに何を追加するのか?

前後の記事を取得するのは、前後の記事へのナビゲーションのためです。 なので記事をまるまま取得する必要はありません。

このサイトの場合だと、次の3つで事足ります。

  • ID(一応)
  • スラッグ(URL生成のため)
  • タイトル

URLを取得してもいいですが、URLはREST APIを利用するフレームワーク側で再生成しとかないと後で面倒なことになりそうだったので不要です。 スラッグから再生成します。

他には、アイキャッチ画像や抜粋、更新日時、カスタムフィールドとかでしょうか。

今回はこのサイトで使う3点に絞って追加していきます。

アイキャッチカスタムフィールドを追加したい場合はそれぞれの記事を参考にしてください。

アクションフックで前後の記事を追加

WordPress上で前後の記事を取得して、次の3点をAPIに追加するコードを書いていきます。

  • ID
  • スラッグ
  • タイトル

前後の記事を取得

まずは前後の記事を取得します。


$prev = get_previous_post();
$next = get_next_post();

戻り値は両方ともWP_Postなので、今回取得するID/スラッグ/タイトル全て入っています。

該当する記事がない場合(一番新しい投稿のnextなど)は空の文字列が返るそうです。

コード全体

register_rest_field()を2回使ってそれぞれ「prev」「next」というキーに追加しました。


add_action( 'rest_api_init', 'api_add_fields' );
function api_add_fields() {
  register_rest_field( 'post',
    'prev',
     array(
      'get_callback'    => 'register_prev_post',
      'update_callback' => null,
      'schema'          => null,
    )
  );
  register_rest_field( 'post',
    'next',
     array(
      'get_callback'    => 'register_next_post',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}
function register_prev_post() {
  global $post;
  
  $prev = get_previous_post();
  
  if ( $prev ) {
    $data = array();
    
    $data['id'] = $prev->ID;
    $data['slug'] = $prev->post_name;
    $data['title'] = $prev->post_title;
    
    return $data;
  }
  return null;
}
function register_next_post() {
  global $post;
  
  $next = get_next_post();
  
  if ( $next ) {
    $data = array();
    
    $data['id'] = $next->ID;
    $data['slug'] = $next->post_name;
    $data['title'] = $next->post_title;
    
    return $data;
  }
  return null;
}

register_prev_post()とregister_next_post()の中身はほとんど同じなので、共通処理の関数をもうひとつ書いてそちらで処理した方がメンテナンス性がいいと思います。

前後の記事を取得した際に空だった場合は、フレームワーク側で処理しやすいようnullを返しています。

あとは…特に書くことはないですね…。

出力結果

このサイトの例で恐縮ですが、上記コードを出力すると次のような値が追加されます。


prev: {
  id: 33,
  slug: 'nuxtjs-install-server',
  title: '初心者がレンタルサーバ上でNuxt.jsをどうにか動かした'
},
next: {
  id: 42,
  slug: 'nuxtjs-head-title',
  title: 'Nuxt.js初心者がtitleタグをページ毎に設定できるようになる物語',
}

コピペで使えるまとめ

WordPressのREST APIで前後の記事を取得するコードのまとめです。 今回はちょっと長いですが、前後それぞれの記事の処理を別関数で書き出しています。


add_action( 'rest_api_init', 'api_add_fields' );
function api_add_fields() {
  register_rest_field( 'post',
    'prev',
     array(
      'get_callback'    => 'register_prev_post',
      'update_callback' => null,
      'schema'          => null,
    )
  );
  register_rest_field( 'post',
    'next',
     array(
      'get_callback'    => 'register_next_post',
      'update_callback' => null,
      'schema'          => null,
    )
  );
}
function register_prev_post() {
  global $post;
  
  $prev = get_previous_post();
  
  return convert_post($prev);
}
function register_next_post() {
  global $post;
  
  $next = get_next_post();
  
  return convert_post($next);
}
function convert_post($post) {
  if ( $post ) {
    $data = array();
    
    $data['id'] = $post->ID;
    $data['slug'] = $post->post_name;
    $data['title'] = $post->post_title;
    
    return $data;
  }
  return null;
}

上記コードは記事のID/スラッグ/タイトルの3点だけ取得するので、他にも要素を追加したい場合はconvert_post()をカスタマイズしてみてください。

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

シェアする: