WordPressのカテゴリAPIを軽量化/カスタマイズする

シェアする:

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

  • WordPress REST APIのカテゴリAPIを軽量化したい人
  • カテゴリAPIに親カテゴリ情報を含めたい人
  • つまりオレ

今回はWordPress REST APIのカテゴリAPIを軽量化・カスタマイズしていきます。

最後にコピペ用コードを置いています。

カテゴリ REST APIのサイズは大きいのか?

10件取得して7KBくらいなので大して大きくはないです。

ただ、これまでの最適化で記事10件が2~3KBです。

カテゴリの方が情報量が少ないにもかかわらずサイズ的には倍以上になっています。

これはあかんでしょ。

カテゴリAPIの中身

カテゴリ1件取得(context=viewの場合)した場合の中身はこんな↓感じです。


{
  "id": 11,
  "count": 5,
  "description": "",
  "link": "https://dev.ore-shika.com/cat/amp/",
  "name": "AMP",
  "slug": "amp",
  "taxonomy": "category",
  "parent": 0,
  "meta": [],
  "_links": {
    "self": [
      {
        "href": "https://dev.ore-shika.com/wp-json/wp/v2/categories/11"
      }
    ],
    "collection": [
      {
        "href": "https://dev.ore-shika.com/wp-json/wp/v2/categories"
      }
    ],
    "about": [
      {
        "href": "https://dev.ore-shika.com/wp-json/wp/v2/taxonomies/category"
      }
    ],
    "wp:post_type": [
      {
        "href": "https://dev.ore-shika.com/wp-json/wp/v2/posts?categories=11"
      }
    ],
    "curies": [
      {
        "name": "wp",
        "href": "https://api.w.org/{rel}",
        "templated": true
      }
    ]
  }
},

投稿APIと同様に「_links」が入っています。 カテゴリは情報量が少ないので_linksのかさばり具合がハンパないですね。

カテゴリ1件589Bのところ、_linksが434Bも占めていました。

contextの違いによるカテゴリAPIの中身

公式によるとカテゴリAPIの要素は以下の9項目。

要素名 view embed
id
count
description
link
name
slug
taxonomy
parent
meta

「context」については「context=embed」の記事を見てください。 REST APIを使うなら絶対に知っておいた方がいいです。

「count」はembedにも入れておいて欲しかったな…。

カテゴリAPIの削除項目

何を削除するかは人によるので、今回は僕基準で考えます。 適宜読み替えてください。

  • 「link」
    カテゴリページのURLはフレームワーク側で再生成するので不要。
  • 「taxonomy」
    カテゴリAPI叩いてんだから「category」が入ってるに決まってます。不要。
  • 「meta」
    どこから入力するか分からないので空です。不要。
  • 「_links」
    利用予定がないしサイズが大きすぎるので不要。

カテゴリAPI軽量化のコード

以下のコードをfunctions.phpに追加します。


//アクションフックの追加
add_action('rest_prepare_category', 'remove_category_links', 10, 3);

//コールバック関数
function remove_category_links($response, $post, $request) {
  //不要な要素の削除
  unset($response->data['link']);
  unset($response->data['taxonomy']);
  unset($response->data['meta']);
  
  //_linksに含まれるキーを取得
  $links = $response->get_links();
  
  //_linksの中身を削除
  foreach ( $links as $key => $value) {
    $response->remove_link($key);
  }
  
  return $response;
}

アクションフックが「rest_prepare_post」から「rest_prepare_category」に変わっていますが原理的には投稿APIから削除する場合と同じです。

「context=embed」でも「count」を表示したい

ついでなので多少カスタマイズしていきます。

このサイトではカテゴリ一覧でも記事数「count」を使用していますが、「context=embed」には「count」が含まれません。

この問題をどうにかしてみます。

rest_prepare_categoryに追加

アクションフック「rest_prepare_category」はcontextの条件分岐が終わった後にフックするようで、次のコードでいけました。


add_action('rest_prepare_category', 'remove_category_links', 10, 3);
function remove_category_links($response, $post, $request) {
  $response->data['count'] = $post->count;
  
  return $response;
}

第2引数の「$post」は、投稿APIから流用しているのでこんな名前ですが、対象とするオブジェクトが入っています。 この場合はcategoryです。

ここからcountを取得しています。

「parent」にカテゴリ詳細を含めたい

カテゴリAPIには親カテゴリのID「parent」がありますが、ここからさらに親カテゴリ情報を取得しようとするともう一度APIを叩かないといけません。

なので事前に親カテゴリ情報も必要な分だけ含めておきます。

「parent」にカテゴリ詳細を追加するコード

「count」同様に、「context=embed」でも親情報が欲しかったのでrest_prepare_categoryに追加しました。


add_action('rest_prepare_category', 'remove_category_links', 10, 3);
function remove_category_links($response, $post, $request) {
  $response->data['parent'] = get_parant_category($post->parent);
  
  return $response;
}

//親カテゴリを取得
function get_parant_category($id) {
  //親カテゴリがない場合
  if ( $id == 0 ) {
    return null;
  }
  
  //カテゴリ情報を取得
  $cat = get_category($id);
  
  $data = array();
  
  //親カテゴリの必要な情報を追加
  $data['id'] = $cat->term_id;
  $data['slug'] = $cat->slug;
  $data['name'] = $cat->name;
  //さらに親があった場合は再帰的に呼び出す
  $data['parent'] = get_parant_category($cat->parent);
  
  return $data;
}

軽量化の成果

元のサイズが6.37KB、軽量化後のサイズが1.12KB。

約80%ちょっとの減量に成功しました。

コピペで使えるコードまとめ

WordPress REST APIのカテゴリAPIを軽量化し、親カテゴリ情報を追加するコードです。 functions.phpに追加します。


//アクションフックの追加
add_action('rest_prepare_category', 'remove_category_links', 10, 3);

//コールバック関数
function remove_category_links($response, $post, $request) {
  //不要な要素の削除
  unset($response->data['link']);
  unset($response->data['taxonomy']);
  unset($response->data['meta']);
  
  //_linksに含まれるキーを取得
  $links = $response->get_links();
  
  //_linksの中身を削除
  foreach ( $links as $key => $value) {
    $response->remove_link($key);
  }
  
  //「count」を「context=embed」でも表示
  $response->data['count'] = $post->count;
  
  //親カテゴリ情報の追加
  $response->data['parent'] = get_parant_category($post->parent);
  
  return $response;
}

//親カテゴリを取得
function get_parant_category($id) {
  //親カテゴリがない場合
  if ( $id == 0 ) {
    return null;
  }
  
  //カテゴリ情報を取得
  $cat = get_category($id);
  
  $data = array();
  
  //親カテゴリの必要な情報を追加
  $data['id'] = $cat->term_id;
  $data['slug'] = $cat->slug;
  $data['name'] = $cat->name;
  //さらに親があった場合は再帰的に呼び出す
  $data['parent'] = get_parant_category($cat->parent);
  
  return $data;
}

何を削除するのか、親カテゴリに何を含めるのか、は人それぞれだと思うのでカスタマイズしてください。

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

シェアする: