Wordpressの記事一覧を取得(WP REST API)

WordpressがAPIを用意してくれている

作成日:2020-12-01, 更新日:2020-12-01

基本:JSONで取得

・Wordpressを設置したURLに「/wp-json/wp/v2/posts?_embed」をつける

ブラウザで確認

▼ドメイン直下にWordpressを設置した場合
・http://example.com/wp-json/wp/v2/posts?_embed

▼ドメイン直下の「ディレクトリ:blog」の下にWordpressを設置した場合
・http://example.com/blog/wp-json/wp/v2/posts?_embed

404になるとき

パーマリンクの設定を「基本」から「日付と投稿名」など別のものに変更する。

ajaxでゴニョゴニョする

var url_wp = '/〇〇';
$.ajax({
  type: 'GET',
  url: url_wp+'/wp-json/wp/v2/posts?_embed',
  dataType: 'json'
}).done(function(json){
  // 取得成功
  alert( JSON.stringify(json) );
}).fail(function(json){
  // 取得失敗
  alert('ブログ記事取得失敗')
});

REST API機能の有効・無効化

▼管理画面が使えなくなる(固定ページを追加しようとしたら真っ白になった)・・・
あまり複雑なコトはしたくない・・・ひとまず緩めに設定する
→途中まで準備はした。でも運用方針でREST API自体を使わなくなったのでひとまず保留

やりたいこと

・他人のアクセスは拒否したい
・戻す値を決めたい
・特定のプラグインは許可する

他人のアクセスは拒否したい

ひとまずリファラから同一HOSTか確認
※ワンタイムトークン(?)とか使ったほうが良いと思う

戻す値を決めたい

通常だとマルっと値を返すので使いたいものだけ返す
※JS側の処理を軽くしたい

▼エンドポイントを自作する必要があるそうだ。
仮に「https://{ドメイン}/wp-json/custom/v0/test」とする。

特定のプラグインは許可する

REST APIを使うプラグインもあるそうだ。

サンプル

▼ファイル構成
・同一階層に新規作成するファイル「_restapi_endpoint.php」
・使っているテンプレートの「functions.php」
・表示するページ:ajax

同一階層に新規作成するファイル「_restapi_endpoint.php」

本来なら記事を取得する処理を記載。ひとまず確認用に値を直接返すだけにしておく。

<?php
return array(
  'id'      => 1,
  'test'    => true,
  'message' => 'テスト'
);

使っているテンプレートの「functions.php」に追記する

function restapi_endpoint_response($file_name, $param = null) {
  $api_file = locate_template($file_name);
  $res      = !empty($api_file) ? include_once $api_file : [];
  $response = new WP_REST_Response($res);
  $response->set_status(200);
  return $response;
}

function restapi_endpoint_callback($param) {
  $filename_getpost = '_restapi_endpoint.php'; // 記事を取得するためのファイル名
  return restapi_endpoint_response($filename_getpost, $param);
}

function restapi_endpoint(){
  // APIのURL: https://{ドメイン}/wp-json/custom/v0/test
  register_rest_route(
    'custom/v0',//ネームスペース
    '/test',    //ベースURL
    [           //オプション
      'methods'             => WP_REST_Server::READABLE,
      'permission_callback' => '__return_true',
      'callback'            => 'restapi_endpoint_callback'
    ]
  );
}
add_action('rest_api_init', 'restapi_endpoint');

// REST API機能の有効・無効化
function deny_restapi_except_plugins( $result, $wp_rest_server, $request ){
  $accept = true;

  // 同一HOSTからの呼び出しのみ許可
  if ( $accept && array_key_exists('HTTP_REFERER', $_SERVER) ) {
    $referer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
    if( $referer_host != $_SERVER['HTTP_HOST'] ){
      $accept = false;
    }
  }
  else {
    $accept = false;
  }

  // 任意のプラグインのみ許可
  if ( $accept ) {
    $namespaces = $request->get_route();
    $seed_accept_plugins = array(
      'contact-form-7/',// Contact Form7
      'oembed/',        // oembed
      'jetpack/',       // Jetpack
      'custom/',        // 自作したエンドポイント
    );
    $tmp_accept = false;
    foreach ( $seed_accept_plugins as $row_accept_plugin ) {
      if( strpos( $namespaces, $row_accept_plugin ) === 1 ){
        $tmp_accept = true;
        break;
      }
    }
    $accept = $tmp_accept;
  }

  if ( $accept ) {
    return $result;
  }
  else {
    return new WP_Error( 'rest_disabled', __( 'The REST API on this site has been disabled.' ), array( 'status' => rest_authorization_required_code() ) );
  }
}
add_filter( 'rest_pre_dispatch', 'deny_restapi_except_plugins', 10, 3 );

表示するページ:ajax

<script>
$(function(){
  var myHost = 'http://example.com';
  var ep = '/custom/v0/test';
  $.ajax({
      type: 'GET',
      url: myHost + '/wp-json' + ep,
      dataType: 'json'
  }).done(function(json){
    alert( JSON.stringify( json ) );
  }).fail(function(json){
    alert('失敗')
  });
});
</script>

関連項目

Wordpressの関数をWordpress外から呼び出す(wp-load.phpの読込み)
wordpressの記事を直接DBから取得