他のWordPressのサイトからページの情報などを取得できるREST API。
あまたある参考ページでは、結構簡単に取得できて、結構簡単に利用できるという内容が多いものの、読んでも具体的な使用方法などが書かれていないことが多く、結局難しいと感じて挫折していませんか?
本ページでは以下のことができるところまでを紹介します。
- 目的のサイトの目的の投稿から取得した情報をブラウザで表示する方法
- 目的のサイトの目的の投稿からREST APIで取得できるデータをすべて表示する方法
- 取得できたデータから、目的の情報を抽出(取得)する方法
- 目的の情報を表示させるショートコードを作る方法
- REST APIのメリット・デメリット
本ページではそんな方のために、より分かりやすく解説することを心掛けた内容にしています。関連ページとともにご覧いただければと思います。
単一の投稿のデータをブラウザ上で表示させてみる
単一の投稿データをREST API経由で引っ張る場合は、基本的に以下のようにURLを指定します。
サイトトップページのURL/wp-json/wp/v2/posts?slug=トップページを除いたURL末尾の文字列
例えば「https://sample.com/samplepost」というページのURLであれば「サイトトップページのURL」は「https://sample.com」、「トップページを除いたURL末尾の文字列」は「samplepost」になります。
ただ注意すべきは、「トップページを除いたURL末尾の文字列」が数字のみの場合と、「トップページを除いたURL末尾の文字列」と「トップページを除いたURL末尾の文字列」の間に別の「/〇〇/」などの階層がある場合です。
前者は、このサイトのように、サイトのパーマリンク設定が「/%post_id%/(投稿ID)」のみになっている場合が多く、その場合は上記URLの「?slug=」を削除して以下のようにしないと情報が取り出せません。
サイトトップページのURL/wp-json/wp/v2/posts/トップページを除いたURL末尾の文字列
後者は、カスタム投稿タイプを使って通常の投稿とは別の投稿の集まりを作って公開している場合。その際は、以下のようにして「posts」をその階層の文字列(〇〇)に変更する必要があります。
サイトトップページのURL/wp-json/wp/v2/〇〇?slug=トップページを除いたURL末尾の文字列
※この場合にスラグが数字だけだったら..というところまでは試していません
さらにいろいろとテストした限りでは、スラグがidの場合は「wp_remote_get()」関数を、その他のスラグの場合は「file_get_contents()」関数を使用し、かつそれぞれに合ったデータ引き出しをしないとうまく取得できません。
ここまででも頭が..となりそうですね。なので、いきなり他人のサイトから何か情報を引っ張れるかしら?ではなく、自身で管理しているサイトで試していただきたいです。
※ちなみに当サイトはREST APIのアクセス制限をかけているため、情報は引き出せませんのであしからず
これをまず理解した上で、プログラムで情報を引っ張り出して..と本当に敷居が高いと思いますので、次項で簡単にショートコードで取得した情報を表示させる方法を紹介します。
ショートコードで引き出せる全情報を表示させてみる
参考プログラムなどでは、ver_dumpなどを使って..なんて書かれていますが、なかなか難しいですね。
そこで以下のコードを有効化しているテーマのfunctions.phpへ追加して、ショートコードを使って目的のページの情報が引き出せるか、また、引き出せるデータは何なのかを表示させてみましょう。
/***** 単一投稿のjsonを取得して表示するショートコード *****/
function pwcn_rest_api_post_data_sc(){
/*** 取得するページの設定 ***/
// サイトのURL
//$home_url = 'ここにサイトトップページのURL';//末尾の「/」は入れない
// 投稿タイプ
//$post_type = 'posts';//投稿は「posts」
// スラッグ
//$slug = 'ここにスラグ';//前後の「/」は入れない
//URLの余分な「/」を取り除く
$slug = ltrim($slug, '/');
$home_url = rtrim($home_url, '/');
/*** jsonデータを取得して整形しなおす ***/
if (ctype_digit($slug)) {//$slugが数字のみの場合
//REST APIのURLを生成
$post_url = $home_url . '/wp-json/wp/v2/' . $post_type . '/' . $slug;
// wp_remote_getを使用してREST APIからデータを取得
$response = wp_remote_get($post_url);
// レスポンス本文を取得
$body = wp_remote_retrieve_body($response);
// JSONデータをデコード
$data = json_decode($body, true);
} else {// それ以外の場合
//REST APIのURLを生成
$post_url = $home_url . '/wp-json/wp/v2/' . $post_type . '?slug=' . $slug;
//jsonデータを取得
$json_data = file_get_contents($post_url);
// JSONデータをデコード
$data = json_decode($json_data, true);
}
//jsonデータを見やすく整形
$formatted_post_data =
esc_html(
json_encode($data,
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
));
// 単一投稿のJSONデータを出力
$result_html = '';//初期値をセット
$result_html .= '<div class="post-json" style="overflow: scroll;">';
$result_html .= '<pre>' .$formatted_post_data . '</pre>';
$result_html .= '</div>';
$result_html .= '<style>.post-json a {text-decoration: none;}</style>';
return $result_html;
}
add_shortcode('rest-post','pwcn_rest_api_post_data_sc');
コードを追加したら、目的のページのURLを調べてコード先頭の方にある以下の文字列を変更します。
- 「ここにサイトトップページのURL」へ目的のページのトップページのURL
- 「ここにスラグ」へ目的のページのトップページURLを除いた文字列
例えば、このサイト内の「https://habone.biz/9638」というURLのページなら、トップページのURLは「https://habone.biz」、スラグは「9638」を指定します。
そして投稿編集画面などを開いて、以下のショートコードを挿入します。
【ショートコード】
[rest-post]
【プレビューしたら表示される内容】
すると、こんな感じでデータを出力することができます(データはこのコードを使って出力したデータをサンプルとして画像化したものです)。
何が書かれているの?というのは次項で説明するとして、こんなデータが引っ張れるのだろうというのが目に見えて分かるようになりましたね。また、自身のサイトの投稿であれば、代替何の内容かも分かると思います。
よくある参考ページでは、この部分が雑に解説されているものが多く、データが引っ張れているかが分からないまま参考コードを書いても何も表示できないという事態となることが多いでしょう。
逆にこのコードを使って、目的のページの情報が引き出せていることが分かれば、その後何かを引っ張って表示させる部分を作った時に表示されない事態となった時に、問題の切り分けができるようになります。
コードではスラグが数字の場合とそうでない場合を判断して、REST APIのエンドポイント(情報表示用のURL)を変えるように書いています
カスタム投稿タイプなどで階層化されている場合はどうするの?という方は冒頭からの文章を読み返してください
本サイトはREST APIのアクセス制限をかけていますので、上記のURLやスラグを指定してもデータは取り出せませんから、ご自身の所有するサイトのページ等へ置き換えて試してください
データの取り出し方(参照方法)
最終的にはデータを引っ張ってきて、その投稿のリンクカードをショートコードで作成するというところまで紹介しますが、その機能自体については後述するとして、前項のような長いコードからどう指定して目的のデータを引っ張り出すのかの書き方の基礎について触れておきます。
前述したようにfile_get_contents()を使う場合と、wp_remote_get()を使う場合がありますので、順に紹介していきます。
【file_get_contents()を使用して取得する場合】
file_get_contents()を使用して取得する場合には、以下のようにして、REST APIから情報を取得(APIを叩くという表現をすることが多いです)します。
//REST APIのURL(エンドポイント)を生成
$post_url = 'トップページのURL/wp-json/wp/v2/投稿タイプ/?slug=スラグ';
//jsonデータを取得
$response_data = file_get_contents( $post_url );
$data = json_decode($response_data, true);
そして、投稿のタイトルと投稿の抜粋を取得する場合には、以下のようにして抽出します。
$post_title = $data[0]['title']['rendered'];
$post_content = $data[0]['excerpt']['rendered'];
上記の$post_titleという変数へ格納する投稿タイトルデータの取得を例に挙げると、$dataという変数の中にある[0]という一番最初にある大きなくくりの中の[‘title’]という次のくくりの中の[‘rendered’]にある値を取得するという意味になります。
実際に前項の取得したコードの一覧上にある該当部分を見てみると、以下のようになっています。
{
"id": 9638,
"date": "2024-04-03T19:11:54",
......
"title": {
"rendered": "\u753b\u50cf\u306e\u64ae\u5f71\u30c7\u30fc\u30bf\uff08EXIF\u60c5\u5831\uff09\u3092\u30e1\u30c7\u30a3\u30a2\u306e\u4e00\u89a7\u3078\u8868\u793a\u3059\u308b\u65b9\u6cd5"
},
1行目が[0]の1つ目の大きなくくり、次のくくりとなっている[‘title’]にある[‘rendered’]の値は..文字が記号に変換されていますが、タイトルの文字列ということになりますね。
こんな感じで目的のデータを抽出するのですが、このデータはjsonという形式で書かれていて、慣れないとなかなか理解できないかも知れませんから、以下に$dataで抽出できるデータと変数を一覧にしておきます。
$data[大くくり]['中くくり']['小くくり']
※文字列は”で囲み、数字は囲まないことがポイントです
内容 | 大くくり | 中くくり | 小くくり |
---|---|---|---|
公開日(サイトの時刻) | [0] | [‘date_gmt’] | |
更新日(サイトの時刻) | [0] | [‘modified_gmt’] | |
ページのURL | [0] | [‘link’] | |
投稿のタイトル | [0] | [‘title’] | [‘rendered’] |
投稿本文 | [0] | [‘content’] | [‘rendered’] |
抜粋 | [0] | [‘excerpt’] | [‘rendered’] |
アイキャッチ画像のID | [0] | [‘featured_media’] |
その他取得できる情報等については以下で詳しく書かれています。
【wp_remote_get()を使用して取得する場合】
wp_remote_get()を使用して取得する場合には、以下のようにしてAPIを叩きます。
//REST APIのURL(エンドポイント)を生成
$post_url = 'トップページのURL/wp-json/wp/v2/投稿タイプ/スラグ';
// wp_remote_getを使用してREST APIからデータを取得
$response = wp_remote_get($post_url);
// レスポンス本文を取得
$body = wp_remote_retrieve_body($response);
// JSONデータをデコード
$data = json_decode($body, true);
そしてwp_remote_get()の場合は先頭末尾が[]で囲まれていないので、大くくりの[0]を使用せず、以下のようにして抽出します。
$title = $data['title']['rendered'];
$post_content = $data['excerpt']['rendered'];
データの抽出方法をまとめると..
- 目的のサイトの投稿のREST APIへ接続
- 一旦データを抽出
- 2のデータを配列として格納
- 3のデータの中から欲しいものを取得する
といった流れになります。
何となくつかめてきましたよね?
ショートコードで情報を取得して表示させる
最後に、タイトルと抜粋を取得して表示させるためのショートコードを作ってみましょう。
以下のコードで、目的の投稿ページの「投稿のタイトル」「抜粋」を表示させることができます。その他の情報を足したり引いたりしたいときは..ここまでの内容を読めば分かると思います。
...と言いながら、結構長いコードになってしまいましたのでコードを見るには以下をクリックしてください。
※コードが長くなってしまった理由はコードの下の「コードが長くなってしまった理由」をご覧ください
クリックしてコードを表示する
function pwcn_rest_api_post_data_for_card_sc(){
/*** 取得するREST APIのサイトURLとスラグを設定 ***/
//トップページのURL
$home_url = '〇〇〇〇';//末尾の「/」は入れない
//投稿タイプのスラグ
$post_type = 'posts';//投稿は「posts」
//スラグ
$slug = '△△△△';//前後の「/」は入れない
//URLの余分な「/」を取り除く
$slug = ltrim($slug, '/');
$home_url = rtrim($home_url, '/');
if (ctype_digit($slug)) {// $slugが数字の場合(パーマリンク設定がIDの場合)
//REST APIのURL(エンドポイント)を生成
$post_url = $home_url . '/wp-json/wp/v2/' . $post_type . '/' . $slug;
//jsonデータを取得
$response = wp_remote_get($post_url); // wp_remote_getを使用してREST APIからデータを取得
$body = wp_remote_retrieve_body($response); // レスポンス本文を取得
$data = json_decode($body, true); // JSONデータをデコード
//必要な項目を変数に格納
if(isset($data)){
$title = $data['title']['rendered'];
$exerpt = $data['excerpt']['rendered'];
}else{
$title = '';
$exerpt = '';
}
} else {// $slugが数字以外の場合(パーマリンク設定がID以外の場合)
//REST APIのURL(エンドポイント)を生成
$post_url = $home_url . '/wp-json/wp/v2/' . $post_type . '?slug=' . $slug;
//jsonデータを取得
$response_data = file_get_contents( $post_url );
$data = json_decode($response_data, true);
//必要な項目を変数に格納
if(isset($data)){
$title = $data[0]['title']['rendered'];
$exerpt = $data[0]['excerpt']['rendered'];
}else{
$title = '';
$exerpt = '';
}
}
// 単一投稿のJSONデータを出力
$result_html = '';//初期値をセット
$result_html .= '<div class="post-data">';
$result_html .= '<h2>タイトル:'.$title.'</h2>';
$result_html .= '<p>抜粋:'.$exerpt.'</p>';
$result_html .= '</div>';
$result_html .= '<style>.post-json a {text-decoration: none;}</style>';
return $result_html;
}
add_shortcode('card-post-data','pwcn_rest_api_post_data_for_card_sc');
コードを追加したら、以下の項目を書き換えます。
- 〇〇〇〇の部分に目的のサイトのトップページのURL
- △△△△の部分にトップページのURLを除く文字列(スラグ)
変更したらコードを保存し、投稿編集画面などで「card-post-data」というショートコードを挿入すれば、「タイトル」と「抜粋」が表示されます(以下表示させたサンプル画像です)。
表示できない場合には、「ショートコードで引き出せる全情報を表示させてみる」へ戻って目的のページの情報が取得できるか?コード中で書き換える部分(〇〇〇〇と△△△△の部分)をきちんと設定しているかを確認ください。
コードが長くなってしまった理由
実はもっと単純なコードで行けると思って作り始めたのですが、以下の場合でデータの取得方法が異なることが自身のテストで判明しました。
- パーマリンク設定が%post_id%のみ(つまりスラグが投稿IDのみ)の場合
- パーマリンク設定がID以外の場合
これについて詳しくは以下のページで紹介しており、この件を踏まえたので、スラグがIDのみかどうかで処理を分ける=コードが長くなってしまったのです。これに気づかなければコードは約半分になるのですが..気づいてしまったので一応対処したコードに書き換えました(笑)。
ただこの件は結構調べてもどこにも掲載されていなかったので、気づいていない人も多いのではないかと推察します。
あれ?アイキャッチ画像は?と思う方は多いかも知れませんね。実はアイキャッチ画像は今回取得した投稿の情報には含まれていません(厳密には、アイキャッチ画像のIDしか提供されていません)。
したがって、アイキャッチ画像を取得して表示させるには、さらにその画像IDを元に画像のAPIから情報を取得(業界用語としては「APIを叩く」と言うそうです)して、それも交えてショートコードで出力する必要があります。
アイキャッチ画像の情報を取得する方法については、以下のページで紹介していますが、本当にややこしいですから、本ページの内容を理解した上でチャレンジしてみてください。
そもそも個別投稿のデータをREST APIで引く必要はあるの?
私自身もこのページを作る(コードを作る)までに、目的の投稿ページのURLによって処理を分けないと正確なデータが引けないことも知り、結構苦労しました(笑)。なので、文末でコードの転載を固く禁じていますが、そのうち本ページと似たコードを提供する輩も出てくるかも知れません。
ただ、多分自身で苦労していないので、そのコードのどこに問題や懸念点があるのかまでは分からないでしょうから、似たコードをみつけて実装してみて不具合や不都合があったら、ぜひ盛大に質問してやってください(笑)。きっと回答はできないと思います。
といじわるなことを書いたところで、何もREST APIをわざわざ使わなくても、何も拒否をする措置をしていなければWordPressサイトではembed(埋め込み)を使った情報の取得はできるようになっていて、単純に目的のページのURLを段落ブロックに貼り付ければ、自動でカード化できるかを判断してくれます。
従って、その手法でカード化される内容で問題がないのであれば、特にREST APIを使う必要はありません。
ただ、REST APIを使うことで、Embedで取得して表示される「タイトル」「抜粋」「サイト名」「アイキャッチ画像」以外の要素を取得して表示できるので、例えば「本文」「公開日」「更新日」なども含めて表示させたい場合には有効でしょう。
本ページでは取り上げていませんが、REST APIを使ったデータ取得は、どこかのサイトの新着情報の一覧を表示させたいといった場合に特に有効だと思うので、本ページの内容を理解した上で取り掛かれば、結構すんなり思ったように情報の取得と表示ができるでしょう。
REST APIのメリット・デメリットについて
ここまでは、どこかのサイトのどこかの投稿のデータを取得することを目的に紹介してきましたが、ここまで読んであることに気づきませんでしたか?
それは、自身が取得できるということは、どこかの誰がが自由に取得することもできてしまうということです。
今回は、単一の投稿に対してのデータ取得をしましたが、エンドポイント(URL)の指定方法やプログラムの書き方によっては、全投稿のデータを一覧で取得して表示させるなんてこともできてしまいます。
自身で管理しているサイトの情報ならまだしも、どこの誰だか分からない人が知識を持っていれば...もうお分かりですね、昔流行ったいわゆる「まとめ」「キュレーション」というような行為ができてしまうんです。
しかも昔の手法で一般的だったRSS情報の取得とは違って、こちらからは件数の制限も内容の制限もできないんです。
さらにはユーザー情報も...ちょっと怖いと思いませんか?
各所に書いていますが、基本的に私が管理するサイトでは、この行為ができないよう措置を講じています。従って、当サイトから本ページのような方法で情報を取得しようとしても拒否されます(やってみてもらって結構です)。
ただ、やみくもにREST APIを封じてしまうと、自身のサイト内での操作で不具合が出てしまうので、上手に制限を行う必要があります。
ここまで読んで少しでも怖いと感じた方は、是非以下のページもご覧ください。
コメントを残す