WordPress

【React × WP】WPのカスタムフィールドのAPIを取得する

部分的にReactを導入していたWP案件で、Reactで構築していた部分を「管理画面から編集できるようにしたい!」という要望がありました。

Yuki
Yuki
ついにAPIを使う日が来た!
ねこくん
ねこくん
どうやって使うの?
Yuki
Yuki
WPではお馴染みのカスタムフィールドを使って、そのAPIを取得して使うよ

まずは実装手順

  1. プラグインの「Smart Custon Fields」をダウンロード
  2. カスタムフィールドを作成
  3. カスタムフィールドのAPIを作成
  4. ReactでAPIデータを取得して、お好きにカスタマイズ
  5. 完成!

1.2は通常通りのカスタムフィールドの実装なので、3から解説していきます。

カスタムフィールドのAPIを作成

WP REST APIを使ってGETメソッドのエンドポイントをfinctions.phpへ追加します。
my_apiの名前は自由なので、変更していただいてOKです。

add_action('rest_api_init', function() {
  register_rest_route( 'wp/v2', '/my_api', array(
      'methods' => 'GET',
      'callback' => 'my_api',
  ));
});

// APIに入れるデータを作成
function my_api() {
  $contents = array();  // こちらに入れていく
  $pickuplist = SCF::get('pickuplist',2);  // 固定ページID「2」で設定した「pickuplist」という名のカスタムフィールドの値を取得
  foreach ($pickuplist as $item) {
    array_push($contents, array(
      "title" => $item['pickup_title'],
      "image" => wp_get_attachment_url( $item['pickup_image']),
      "text" => $item['pickup_text'],
  ));
  }
   return $contents;
}

今回はカスタムフィールドの繰り返しデータを入れていきました。

↓ちなみに、こちらが作成したカスタムフィールドです。

サイトがhttp://hogehoge.comの場合、http://hogehoge.com/wp-json/wp/v2/my_apiへアクセスしてみてください。

jsonが返ってきたら成功です!

ReactでAPIデータを取得して、お好きにカスタマイズ

それでは、いよいよReactからAPIデータを取得してみましょう。
Axiosを使うので、まずは install します。

npm install axios

そしてこのような形で実装します。

import { useEffect, useState } from 'react';
import axios from 'axios';

type pickupItem = {
  title: string;
  image: string;
  text: string;
};

export const PickupList = () => {
  const [pickupContents, setPickupContents] = useState<Array<pickupItem>>([]);
  useEffect(() => {
    const href = window.location.href;
    axios
      .get<Array<pickupItem>>(`${href}wp-json/wp/v2/my_api`)
      .then((res) => {
        setPickupContents(res.data);  //jsonデータをセット
      })
      .catch((error) => console.log(error));
  }, []);

  return (
    <>
      {pickupContents.map((content, index) => (
        <div className="pickup-content" key={index}>
          <div className="pickup-head">
            <figure className="pickup-figure">
              <img
                src={content.image}
                className="pickup-image"
                alt={content.title}
              />
            </figure>
            <h3 className="pickup-title">{content.title}</h3>
          </div>
          <p className="pickup-text">{content.text}</p>
        </div>
      ))}
    </>
  );
};

以上で完成です!

ねこくん
ねこくん
カスタムフィールド以外にも投稿データとかでもAPI作成できそうだね
Yuki
Yuki
そうだね!いろいろ応用が効いて便利♪

実装コードまとめ

こちらが今回実装したコードのまとめです。

📌 WP側 functions.php

add_action('rest_api_init', function() {
  register_rest_route( 'wp/v2', '/my_api', array(
      'methods' => 'GET',
      'callback' => 'my_api',
  ));
});

function my_api() {
  $contents = array();
  $pickuplist = SCF::get('pickuplist',2);
  foreach ($pickuplist as $item) {
    array_push($contents, array(
      "title" => $item['pickup_title'],
      "image" => wp_get_attachment_url( $item['pickup_image']),
      "text" => $item['pickup_text'],
  ));
  }
   return $contents;
}

📌 React側

import { useEffect, useState } from 'react';
import axios from 'axios';

type pickupItem = {
  title: string;
  image: string;
  text: string;
};

export const PickupList = () => {
  const [pickupContents, setPickupContents] = useState<Array<pickupItem>>([]);
  useEffect(() => {
    const href = window.location.href;
    axios
      .get<Array<pickupItem>>(`${href}wp-json/wp/v2/my_api`)
      .then((res) => {
        setPickupContents(res.data); 
      })
      .catch((error) => console.log(error));
  }, []);

  return (
    <>
      {pickupContents.map((content, index) => (
        <div className="pickup-content" key={index}>
          <div className="pickup-head">
            <figure className="pickup-figure">
              <img
                src={content.image}
                className="pickup-image"
                alt={content.title}
              />
            </figure>
            <h3 className="pickup-title">{content.title}</h3>
          </div>
          <p className="pickup-text">{content.text}</p>
        </div>
      ))}
    </>
  );
};

ご質問や、「こうした方が良いよ!」とアドバイスくださる心優しい方がいらっしゃいましたらお気軽にコメントください😊(とても喜びます)

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です