バックエンド PlatoBlockchain Data Intelligence の WordPress ブロックでの外部 API データのレンダリング。 垂直検索。 あい。

バックエンドの WordPress ブロックで外部 API データをレンダリングする

前回の記事の続きです 「フロントエンドの WordPress ブロックで外部 API データをレンダリングする」. 最後の XNUMX つでは、外部 API を取得して、WordPress サイトのフロントエンドでフェッチされたデータをレンダリングするブロックと統合する方法を学びました。

問題は、WordPress ブロック エディターでデータが表示されないようにする方法でこれを達成したことです。 つまり、ブロックをページに挿入できますが、プレビューは表示されません。 ブロックが公開されたときにのみブロックが表示されます。

前回の記事で作成したブロック プラグインの例をもう一度見てみましょう。 今回だけ、WordPress の JavaScript と React エコシステムを利用して、バックエンドのブロック エディターでもそのデータをフェッチしてレンダリングします。

中断した場所

これを開始すると、 ここにデモがあります 参照できる最後の記事にたどり着いた場所。 あなたは私が render_callback これにより、PHP ファイルの属性を利用してコンテンツをレンダリングできるようになります。

これは、ネイティブの WordPress または PHP 関数を使用して動的ブロックを作成する必要がある場合に役立ちます。 しかし、WordPress の JavaScript と React (具体的には JSX) エコシステムだけを利用して、データベースに保存されている属性とともに静的 HTML をレンダリングする場合は、 Edit & Save ブロックプラグインの機能。

  •   Edit 関数は、ブロック エディターで見たいものに基づいてコンテンツをレンダリングします。 ここにインタラクティブな React コンポーネントを配置できます。
  •   Save 関数は、フロント エンドで見たいものに基づいてコンテンツをレンダリングします。 通常の React コンポーネントやフックをここに置くことはできません。 属性とともにデータベースに保存される静的 HTML を返すために使用されます。

  Save 関数は、今日私たちがぶらぶらしている場所です。 フロントエンドでインタラクティブなコンポーネントを作成できますが、そのためには手動でそれらを含め、外部にアクセスする必要があります Save 前回の記事で行ったように、ファイル内の関数。

というわけで、前回の記事と同じ内容を取り上げますが、今回はブロック エディターでプレビューを確認できます。 フロントエンドに公開します。

ブロックの小道具

意図的に説明を省いた edit 前回の記事で関数の props を使用したのは、主要なポイントであるレンダリングから焦点が外れていたからです。

あなたが React のバックグラウンドを持っている場合は、私が話していることを理解している可能性がありますが、これに慣れていない場合は、お勧めします React ドキュメントでコンポーネントと小道具をチェックアウトする.

ログを記録すると props オブジェクトをコンソールに送信すると、ブロックに関連する WordPress 関数と変数のリストが返されます。

バックエンドの WordPress ブロックで外部 API データをレンダリングする

必要なのは attributes オブジェクトと setAttributes から分解しようとしている関数 props 私のコードのオブジェクト。 前回の記事で、RapidAPI のコードを変更して、API データを保存できるようにしました。 setAttributes(). props は読み取り専用であるため、直接変更することはできません。

ブロック props は状態変数に似ています。 setState ただし、React はクライアント側で動作し、 setAttributes() 投稿を保存した後、属性を WordPress データベースに永続的に保存するために使用されます。 だから、私たちがする必要があるのは、それらをに保存することです attributes.data そして、それをの初期値として呼び出します useState() 変数に保存します.

  edit function

で使用した HTML コードをコピーして貼り付けます。 football-rankings.php 前回の記事で少し編集して、JavaScript の背景に移行します。 前回の記事で、フロント エンドのスタイリングとスクリプト用に XNUMX つの追加ファイルを作成した方法を覚えていますか? 現在のアプローチでは、これらのファイルを作成する必要はありません。 代わりに、すべてを Edit 機能。

完全なコード
import { useState } from "@wordpress/element";
export default function Edit(props) {
  const { attributes, setAttributes } = props;
  const [apiData, setApiData] = useState(null);
    function fetchData() {
      const options = {
        method: "GET",
        headers: {
          "X-RapidAPI-Key": "Your Rapid API key",
          "X-RapidAPI-Host": "api-football-v1.p.rapidapi.com",
        },
      };
      fetch(
        "https://api-football-v1.p.rapidapi.com/v3/standings?season=2021&league=39",
          options
      )
      .then((response) => response.json())
      .then((response) => {
        let newData = { ...response }; // Deep clone the response data
        setAttributes({ data: newData }); // Store the data in WordPress attributes
        setApiData(newData); // Modify the state with the new data
      })
      .catch((err) => console.error(err));
    }
    return (
      
{apiData && (
Rank
Logo
Team name
GP
GW
GD
GL
GF
GA
Pts
Form history
{/* Usage of [0] might be weird but that is how the API structure is. */} {apiData.response[0].league.standings[0].map((el) => { {/* Destructure the required data from all */} const { played, win, draw, lose, goals } = el.all; return (
{el.rank}
Rendering External API Data in WordPress Blocks on the Back End PlatoBlockchain Data Intelligence. Vertical Search. Ai.
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => { return (
{result}
); })}
); } )}
)}
); }

Reactフックを含めました useState() から @wordpress/element React ライブラリから使用するのではなく。 これは、通常の方法でロードすると、使用しているブロックごとに React がダウンロードされるためです。 しかし、私が使用している場合 @wordpress/element 単一のソース、つまり React 上の WordPress レイヤーからロードされます。

今回は、コードもラップしていません。 useEffect() ただし、ボタンをクリックしたときにのみ呼び出される関数内で、フェッチされたデータのライブ プレビューが表示されます。 と呼ばれる状態変数を使用しました apiData リーグテーブルを条件付きでレンダリングします。 したがって、ボタンがクリックされてデータが取得されたら、設定しています apiData 内の新しいデータに fetchData() 利用可能なサッカーのランキング表の HTML を使用した再レンダリングがあります。

投稿が保存され、ページが更新されると、リーグ テーブルが消えていることがわかります。 これは、空の状態を使用しているためです (null)のための apiDataの初期値。 投稿が保存されると、属性が attributes.data オブジェクトの初期値として呼び出します。 useState() このような変数:

const [apiData, setApiData] = useState(attributes.data);

  save function

ほぼ同じことを save 機能ですが、少し変更します。 たとえば、フロント エンドの「Fetch data」ボタンは必要ありません。 apiData 状態変数も不要です。 edit 関数。 しかし、ランダムが必要です apiData チェックする変数 attributes.data そうしないと、未定義のエラーがスローされ、ブロック エディターの UI が空白になります。

完全なコード
export default function save(props) {
  const { attributes, setAttributes } = props;
  let apiData = attributes.data;
  return (
    
      {/* Only render if apiData is available */}
      {apiData && (
        
Rank
Logo
Team name
GP
GW
GD
GL
GF
GA
Pts
Form history
{/* Usage of [0] might be weird but that is how the API structure is. */} {apiData.response[0].league.standings[0].map((el) => { const { played, win, draw, lose, goals } = el.all; return (
{el.rank}
Rendering External API Data in WordPress Blocks on the Back End PlatoBlockchain Data Intelligence. Vertical Search. Ai.
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => { return (
{result}
); })}
); })}
)} ); }

を変更する場合 save ブロック エディタにブロックが既に存在する後に関数を実行すると、次のようなエラーが表示されます。

ブロックに予期しないエラーが含まれているというエラー メッセージが表示された、WordPress ブロック エディターのサッカー ランキング ブロック。
バックエンドの WordPress ブロックで外部 API データをレンダリングする

これは、保存されたコンテンツのマークアップが新しいコンテンツのマークアップと異なるためです。 save 関数。 私たちは開発モードにいるので、現在のページからブロックを削除して、新しいブロックとして再挿入する方が簡単です — そうすれば、更新されたコードが代わりに使用され、同期が元に戻ります.

削除して再度追加するというこの状況は、 render_callback 出力は動的で、save 関数ではなく PHP によって制御されるためです。 したがって、それぞれの方法にはそれぞれ長所と短所があります。

Tom Nowell が、ビジネスでしてはいけないことについて徹底的に説明しています。 save の機能 このスタックオーバーフロー 回答.

エディターとフロント エンドでのブロックのスタイリング

スタイリングに関しては、前回の記事で見たものとほぼ同じになる予定ですが、コメントで説明したいくつかの小さな変更があります. ここでは完全なスタイルを提供しているだけです。これは、コピーして貼り付けたいものではなく、概念実証にすぎないためです (このようにスタイル設定されたサッカー ランキングを表示するためのブロックが本当に必要な場合を除きます)。 また、ビルド時に CSS にコンパイルされる SCSS をまだ使用していることに注意してください。

エディタースタイル
/* Target all the blocks with the data-title="Football Rankings" */
.block-editor-block-list__layout 
.block-editor-block-list__block.wp-block[data-title="Football Rankings"] {
  /* By default, the blocks are constrained within 650px max-width plus other design specific code */
  max-width: unset;
  background: linear-gradient(to right, #8f94fb, #4e54c8);
  display: grid;
  place-items: center;
  padding: 60px 0;

  /* Button CSS - From: https://getcssscan.com/css-buttons-examples - Some properties really not needed :) */
  button.fetch-data {
    align-items: center;
    background-color: #ffffff;
    border: 1px solid rgb(0 0 0 / 0.1);
    border-radius: 0.25rem;
    box-shadow: rgb(0 0 0 / 0.02) 0 1px 3px 0;
    box-sizing: border-box;
    color: rgb(0 0 0 / 0.85);
    cursor: pointer;
    display: inline-flex;
    font-family: system-ui, -apple-system, system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 16px;
    font-weight: 600;
    justify-content: center;
    line-height: 1.25;
    margin: 0;
    min-height: 3rem;
    padding: calc(0.875rem - 1px) calc(1.5rem - 1px);
    position: relative;
    text-decoration: none;
    transition: all 250ms;
    user-select: none;
    -webkit-user-select: none;
    touch-action: manipulation;
    vertical-align: baseline;
    width: auto;
    &:hover,
    &:focus {
      border-color: rgb(0, 0, 0, 0.15);
      box-shadow: rgb(0 0 0 / 0.1) 0 4px 12px;
      color: rgb(0, 0, 0, 0.65);
    }
    &:hover {
      transform: translateY(-1px);
    }
    &:active {
      background-color: #f0f0f1;
      border-color: rgb(0 0 0 / 0.15);
      box-shadow: rgb(0 0 0 / 0.06) 0 2px 4px;
      color: rgb(0 0 0 / 0.65);
      transform: translateY(0);
    }
  }
}
フロントエンド スタイル
/* Front-end block styles */
.wp-block-post-content .wp-block-football-rankings-league-table {
  background: linear-gradient(to right, #8f94fb, #4e54c8);
  max-width: unset;
  display: grid;
  place-items: center;
}

#league-standings {
  width: 900px;
  margin: 60px 0;
  max-width: unset;
  font-size: 16px;
  .header {
    display: grid;
    gap: 1em;
    padding: 10px;
    grid-template-columns: 1fr 1fr 3fr 4fr 3fr;
    align-items: center;
    color: white;
    font-size: 16px;
    font-weight: 600;
    background-color: transparent;
    background-repeat: no-repeat;
    background-size: contain;
    background-position: right;

    .stats {
      display: flex;
      gap: 15px;
      & > div {
        width: 30px;
      }
    }
  }
}
.league-table {
  background: white;
  box-shadow:
    rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
    rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
  padding: 1em;
  .position {
    width: 20px;
  }
  .team {
    display: grid;
    gap: 1em;
    padding: 10px 0;
    grid-template-columns: 1fr 1fr 3fr 4fr 3fr;
    align-items: center;
  }
  .team:not(:last-child) {
    border-bottom: 1px solid lightgray;
  }
  .team-logo img {
    width: 30px;
    top: 3px;
    position: relative;
  }
  .stats {
    display: flex;
    gap: 15px;
    & > div {
      width: 30px;
      text-align: center;
    }
  }
  .last-5-games {
    display: flex;
    gap: 5px;
    & > div {
      width: 25px;
      height: 25px;
      text-align: center;
      border-radius: 3px;
      font-size: 15px;
    & .result-W {
      background: #347d39;
      color: white;
    }
    & .result-D {
      background: gray;
      color: white;
    }
    & .result-L {
      background: lightcoral;
      color: white;
    }
  }
}

これを追加します src/style.scss エディターとフロントエンドの両方でスタイリングを処理します。 編集者のアクセスが必要になるため、デモの URL を共有することはできませんが、デモを確認できるようにビデオを録画しています。


かなりきれいですよね? これで、フロント エンドでレンダリングするだけでなく、ブロック エディターで API データを取得してレンダリングする、完全に機能するブロックができました。更新ボタンで起動できます。

しかし、私たちが取りたいのなら フル WordPress Block Editor の利点として、ブロックの UI 要素のいくつかを ブロック コントロール 色、タイポグラフィ、間隔の設定など。 これは、ブロック開発の学習過程における素晴らしい次のステップです。

タイムスタンプ:

より多くの CSSトリック