WordPress REST APIでブログ一覧ページを作成する

はじめに

今回の記事では WordPress REST API を使用して、ホームページにブログの一覧を表示する方法をお伝えします。

ブログの一覧を表示するだけでなく、投稿日時で絞り込んだり、カテゴリーで絞り込む方法についても詳しく解説します。

前半は WordPress REST API の解説を行い、後半は WESEEK ホームページの WordPress REST API を用いたブログページの実装を紹介します。

WordPress REST API とは

まず REST API について解説します。

REST (Representational State Transfer) API は、API (アプリケーションプログラミングインターフェイス) の一種で、Web アプリケーション同士の通信をサポートします。

REST は多くの場合 HTTP を使用しており、JSON(JavaScript Object Notation)という形式でデータを転送します。

REST を用いることでシンプルかつ効率的なやり取りを行えるため、Web 上のデータを取得する際に最もよく使用される選択肢となっています。

REST で用いる代表的な HTTP コマンドには以下のものがあります。

  • GET: 指定したリソースを取得する
  • POST: 新しいリソースを作成する
  • PUT: 既存のリソースを更新する
  • DELETE: 既存のリソースを削除する

WordPress REST API とは、これらの HTTP リクエストを送信することで WordPress の記事のデータを取得したり、記事の投稿を行える API です。

WordPress REST API での操作

では実際に WordPress REST API を用いて様々な操作を行います。

今回の解説では HTTP のリクエストに curl コマンドを使用するので、実際に試してみたいという方はダウンロードしておきましょう。

記事データの取得

WordPress REST API で最も良く実行されるであろう、記事データの取得について解説します。
記事データの取得は、後述する記事の投稿・更新・削除と異なり、記事が公開されている状態であれば誰でも実行できます。

記事データ取得のための基本的なコマンドは以下のようになります。

$ curl -X GET https://[API route]/wp-json/wp/v2/posts?[オプション]

(curl のデフォルトの HTTP メソッドは GET なので、-X GET の部分は省略可)

API route の部分には、弊社の場合
会社ブログ: weseek.co.jp/blog
技術ブログ: weseek.co.jp/tech
が入ります。

(WordPress REST API では、厳密には /wp-json/ まで含むものを API route と言います。 詳細)

この記事では、操作対象の WordPress に https://wpdemo.net/ をお借りしてコマンドを紹介します。

では実際にコマンドを打ち込んで実行結果を確認します。

$ curl -X GET https://wpdemo.net/wp-json/wp/v2/posts
[{"id":970,"date":"2021-10-07T11:00:38","date_gmt":"2021-10-07T15:00:38","guid":{"rendered":"https:\/\/wpdemo.net\/?p=970"},"modified":"2021-10-07T11:01:07","modified_gmt":"2021-10-07T15:01:07","slug":"update-override-demo-parameters","status":"publish","type":"post","link":"https:\/\/wpdemo.net\/news\/update-override-demo-parameters-p970","title":{"rendered":"Update: Override Demo Parameters"},"content":{"rendered":"<div class='app_site_dl_wrapper'> ...(省略)

json 形式で記事のデータが取得できていることが確認できます。
オプションを何も渡さなかった場合は記事の中身の HTML まで取得できるので、データの分量はなかなかの大きさになります。

次にオプションについて解説します。
URL のパラメータに値を渡すことで、より具体的な条件で記事のデータを取得できます。

どのようなパラメータを設定できるのか、よく使われるものから順に解説します。

全てのパラメータを知りたい場合はこちらをご覧ください。
https://developer.wordpress.org/rest-api/reference/posts/#arguments

パラメータ名 初期値 説明
_fields author, id, excerpt, title, link を指定することができる。指定したフィールドのデータのみ取得する。
_embed 通常のデータに加えてアイキャッチ画像などのデータを得られる。このパラメータは値を必要としない。
per_page 10 得られる記事データの最大数を設定する。
page 1 指定したページの記事を取得する。
order desc 取得できるデータを昇順か降順で並び替える、asc or desc を指定する。
orderby date author, date, id, include, modified, parent, relevance, slug, include_slugstitle のいずれかから指定可能で、指定した属性でソートされる。
categories 指定したカテゴリーで絞り込まれた記事を取得する。
tags 指定したタグで絞り込まれた記事を取得する。
author 指定した著者名で絞り込まれた記事を取得する。
after 指定した日時より後に投稿された記事を取得する。
before 指定した日時より前に投稿された記事を取得する。

例えば3つ分の記事の id, title, author の情報のみを取得したい場合は、以下のようなコマンドを実行することで取得できます。

$ curl -X GET https://wpdemo.net/wp-json/wp/v2/posts?_fields=author,id,title\&per_page=3

(curl コマンドで複数のクエリパラメータを指定する場合は & をエスケープする必要がある)

[{"id":970,"title":{"rendered":"Update: Override Demo Parameters"},"author":2},{"id":920,"title":{"rendered":"How to Create a Demo WordPress Site"},"author":2},{"id":832,"title":{"rendered":"Why You Shouldn&#8217;t Use Your Existing Hosting to Host Your WordPress Theme or Plugin Demo"},"author":2}]

また、posts の後ろに記事の id を指定することで、単一の記事データを取得できます。

$ curl -X GET https://wpdemo.net/wp-json/wp/v2/posts/1

記事の投稿

WordPress REST API で記事を投稿する方法について解説します。

先ほどの記事データの取得は記事が公開されている状態であれば誰でも取得できました。
しかし記事の投稿・更新・削除は認証を行わなければ実行できません。

WordPress の認証はいくつかの種類が存在し、Cookie 認証や OAuth 認証などが存在しますが、この記事では curl コマンドで記事の投稿などの操作を行うため、最も分かりやすい Basic 認証を用いて認証を行います。

記事を投稿する場合、さらに Content-Type の指定や、title, contents などの投稿内容の情報を渡す必要があります。
Content-Type を指定しなかった場合は 変数名=値 の形式で値を送信することになります。

curl コマンドで記事を投稿する場合は以下のようになります。

$ curl -X POST --user ユーザー名:パスワード https://wpdemo.net/wp-json/wp/v2/posts -H "Content-Type: application/json" -d '{"title": "タイトル", "contents": "コンテンツ"}'

--user オプションで WordPress のユーザー名とパスワードを指定して認証します。
今回は json 形式でデータを渡すため、Content-Type には application/json を指定しています。

この例では記事のタイトルとコンテンツのみ指定していますが、著者名やタグ、カテゴリーなど非常に多くの項目を渡せます。
詳しく知りたいという方はこちらをご覧ください。
https://developer.wordpress.org/rest-api/reference/posts/#schema

記事の更新

すでに投稿されている記事を更新する場合について解説します。

方法は記事の投稿とほとんど同じで、違いはエンドポイントに更新対象記事の ID を含めることくらいです。
curl コマンドで記事を更新する場合は以下のようになります。

$ curl -X POST --user ユーザー名:パスワード https://wpdemo.net/wp-json/wp/v2/posts/対象記事のID -H "Content-Type: application/json" -d '{"title": "更新後のタイトル", "contents": "更新後のコンテンツ"}'

記事の削除

投稿されている記事を削除する場合について解説します。

削除のやり方は非常にシンプルで、対象記事の ID が含まれたエンドポイントに対して HTTP の DELETE メソッドでリクエストを投げるだけです。
curl コマンドで記事を削除する場合は以下のようになります。

$ curl -X DELETE --user ユーザー名:パスワード https://wpdemo.net/wp-json/wp/v2/posts/対象記事のID

弊社ホームページのブログ一覧画面の紹介

前半では WordPress REST API の解説を行いました。

ここからは、弊社 (株式会社WESEEK) のホームページのブログ一覧画面を紹介します。

https://weseek.co.jp/ja/blog/

主に4つの機能があります。

  1. ブログ切り替え
  2. 投稿年による絞り込み
  3. カテゴリーによる絞り込み
  4. ページネーション

ブログ切り替え

弊社には2種類のブログがあり「WESEEK BLOG」は会社の紹介や社内イベントなどの記事が投稿され、「TECH BLOG」は弊社の社員が外部に向けて公開する技術ブログとなっています。
画面上部のボタンから、この2種類の記事を切り替えられるようになっています。

投稿年による絞り込み

デフォルトの状態では全ての記事が表示されますが、左上のドロップダウンから年を選択することにより、その年に投稿されたブログのみを表示させられます。

カテゴリーによる絞り込み

記事のタイトル下にあるカテゴリー名をクリックすることで、そのカテゴリーの記事を絞り込めます。
カテゴリー選択後、右上の×ボタンを押すことによりカテゴリーの選択を解除できます。

ページネーション

弊社のブログ一覧画面では最大で1度に9つの記事が表示されるように設定されており、記事数が9つよりも多い場合は下部のボタンを押すことでページの切り替えが行えるようになっています。
また、このページネーション機能は年やカテゴリーによる絞り込みを考慮したものとなっています。

弊社ホームページのブログページの実装について解説

最後に、弊社のホームページではどのようにしてブログページを作成しているのかについて解説します。なお、今から紹介するコードは全て vue.js で書かれています。

記事データを取得する

async getBlogListAndMaxPage(page, selectedBlogType, selectedYear, selectedCategory) {
  let requestURL = `https://weseek.co.jp/${selectedBlogType}/wp-json/wp/v2/posts?_embed&per_page=9&page=${page}`;

  if (selectedCategory) {
    requestURL += `&categories=${selectedCategory}`;
  }

  if (selectedYear !== 'ALL') {
    requestURL += `&after=${selectedYear}-01-01T00:00:00.00&before=${selectedYear}-12-31T23:59:59.99`;
  }

  try {
    const res = await fetch(requestURL);
    this.blogList = await res.json();
    this.maxPage = Number(res.headers.get('x-wp-totalpages'));
  }
  catch (error) {
    throw new Error(error);
  }
}

まず、記事データと最大ページ数を取得するためのメソッドとして getBlogListAndMaxPage メソッドを定義しています。
引数には取得するページ、選択されているブログの種類、選択されている年、選択されているカテゴリーを渡します。

let requestURL = `https://weseek.co.jp/${selectedBlogType}/wp-json/wp/v2/posts?_embed&per_page=9&page=${page}`;

最初に requestURL を定義しています。
弊社には2種類の WordPress があるので selectedBlogType で出し分けています。

オプションでは、サムネイルを表示させたいため _embed のパラメータで追加の情報を取得しています。
さらに、1ページあたり9つの記事を表示させるため、per_page には9を指定し、page には表示するページを指定します。

if (selectedCategory) {
  requestURL += `&categories=${selectedCategory}`;
}

カテゴリーが選択されている場合は categories パラメータを requestURL に追加することでカテゴリーによる絞り込みを行います。

if (selectedYear !== 'ALL') {
  requestURL += `&after=${selectedYear}-01-01T00:00:00.00&before=${selectedYear}-12-31T23:59:59.99`;
}

次は年による絞り込みで、selectedYear は ALL という文字列もしくは年が渡るので、ALL 以外の時に beforeafter のパラメータを追加します。

そしていよいよ requestURL を元にデータの取得を行います。
データの取得には Fetch API を使用します。

最大ページ数だけは少し特殊で、レスポンスの body ではなく header に情報が含まれているので、res.headers.get('x-wp-totalpages') で取得してそれを数字に変換しています。

const res = await fetch(requestURL);
this.blogList = await res.json();
this.maxPage = Number(res.headers.get('x-wp-totalpages'));

これにより this.blogList に現在のページのブログ一覧の情報が格納されました。

最大ページ数を取得することにより、ページネーション機能で最大ページ数を超えるページを選択できないようにしています。

サムネイルを表示する

先ほど取得した blogList から、このようにしてリンクやタイトルを表示させられます。

<div v-for="blog in blogList" :key="blog.id">
  <a :href="blog.link" target="_blank">
    {{ blog.title }}
  </a>
</div>

取得したデータから、サムネイルを表示させる方法を解説します。

サムネイルなどの情報はオプション無しでは取得できず、リクエストのパラメータに _embed を含めることで取得できます。
これにより新しく追加されたデータは blog._embedded の中に含まれます。

サムネイルの source_url を取得できればサムネイル画像を表示できます。
source_url は非常に深い位置にあり、

blog._embedded['wp:featuredmedia'].[0].media_details.sizes.サイズ.source_url

で取得できます。

1つ注意点があり、サイズの部分には medium or large or full が入りますが、サムネイルの画像サイズによっては medium が無かったりします。
かと言って全て full で指定してしまうと、サムネイルの画像サイズが大きかった場合に表示速度などで悪影響が出てしまうので、medium -> large -> full のように小さい順で探して表示するのが良いと思われます。

取得した source_url を img タグの src に渡すことで、記事のサムネイルを表示できます。

<img :src="source_url">

カテゴリーIDからカテゴリー名を取得して表示する

取得したデータから、タイトルやURL、サムネイルを表示できました。
しかし、取得した記事データの author, categories, tags に関しては、それぞれの値が直接取得できるのではなく ID が取得されます。

ここでは、取得したカテゴリーの ID から、その ID に対応するカテゴリーの値を取得して表示させる方法について解説します。

これまで、/wp/v2/posts を指定して記事の情報を取得してきました。
しかし WordPress REST API には他にもさまざまな種類のエンドポイントが存在します。

カテゴリー ID をカテゴリー名に変換するために、ID と名前の対応表が必要ですが、これは /wp/v2/categories のエンドポイントから取得できます。他のエンドポイントについてはこちらから確認できます。

どのエンドポイントも /wp/v2/posts と同様にオプションを指定できます。
今回必要なのは id と name のフィールドだけなので、_fiedls パラメータを指定します。

curl -X GET https://wpdemo.net/wp-json/wp/v2/categories?_fields=id,name
[{"id":1,"name":"General"},{"id":6,"name":"News"},{"id":4,"name":"WordPress"}]

カテゴリー情報を取得するコードと表示するコードを紹介します。

async getCategoryList() {
  const res = await fetch('https://weseek.co.jp/tech/wp-json/wp/v2/categories?_fields=id,name&per_page=100');
  this.categoryList = await res.json();
},
showCategoryName(categoryID) {
  return this.categoryList.find(c => c.id === categoryID)?.name;
}

/wp/v2/categories エンドポイントも他と同様に per_page の初期値は10です。
全てのカテゴリー情報を取得するために、per_page に設定可能な最大値である100を指定しています。
もしカテゴリーの種類が100よりも多い場合、ページを分けて取得した後に連結しなければならないので少し面倒になります。

id と name の対応表を取得した後は、find メソッドを使用して id に対応する name を取得しています。

さいごに

WordPress REST API を用いることで WordPress の情報を取得してホームページに表示できました。
WordPress REST API では、直接 WordPress を操作するのと同じくらい非常に多くの操作が行えるため、工夫次第ではホームページにもっと面白い機能を追加できそうです。
興味を持った方はぜひ触ってみてください。