WordPress の REST API で投稿の記事一覧か個別記事かを判定する

経緯

WordPress の REST API で出力されるデータをカスタマイズする際に、記事の一覧なのか個別の記事なのかを判定したくなったので。

例えば、「記事一覧のデータでは本文はいらず、個別記事のデータの場合のみ本文をデータに出力する」みたいなことをしたくなったときに、 is_single() のようなテンプレートタグがないかな、と。

……検索してみましたが見当たらなかったので、自前で判定することにしました。

実装

<?php
/*
Plugin Name: Filter REST
Description: REST API の出力結果をフィルタリングするプラグイン (パーマリンク設定は「基本」または「数字ベース」にしてください)
Version: 0.0.2
Author: アルム=バンド
*/

/**
 * Filter REST : REST API の出力結果をフィルタリングするプラグイン
 */
class FilterREST
{
    /**
     * __construct : プラグイン有効時にメソッドを呼ぶ
     *
     */
    public function __construct() {
        // 有効化の際に発動
        add_action(
            'rest_prepare_post',
            [
                $this,
                'remove_data',
            ],
            10,
            3
        );
    }
    /**
     * remove_data                : _links や不要な値を非出力にする
     *
     * @param {Object} $response  : レスポンスとして返却するデータ
     * @param {Object} $post      :
     * @param {Array} $request    : リクレストデータ
     *
     * @return {Object} $response : レスポンスとして返却するデータ
     *
     */
    public function remove_data ( $response, $post, $request )
    {
        // 略
        $is_single = false;
        if ( preg_match( '/posts\/[\d]+/i', $request->get_route() ) ) {
            // route が .../posts/{記事ID} の形式ならば単独記事のデータ取得と見なす
            $is_single = true;
        }
        if (!$is_single) {
            // 記事一覧のデータ取得ならばコンテンツ本文を削除
            unset( $response->data['content'] );
        }

        return $response;
    }
}

// instantiate
if( !is_admin() ) {
    // 管理者画面以外
    $filterrest = new FilterREST();
}

以前のコードに判定と処理を足してみました。

is_single() っぽいものが見付からなかったので、力業で GETリクエストの URL(ルーティング) が /wp/v2/posts/{記事ID} の形式ならば個別記事、そうではない /wp/v2/posts(最後にスラッシュ+記事IDの数字が付かない) の形式ならば記事一覧、というイメージです。ルーティングの情報は $requestオブジェクト から get_route()メソッド で引っ張ってきています。

一応これでできましたが……もう少しスマートにできる方法はないのでしょうか?

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。