Rendern externer API-Daten in WordPress-Blöcken im Back-End PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.

Rendern von externen API-Daten in WordPress-Blöcken im Backend

Dies ist eine Fortsetzung meines letzten Artikels über „Rendern externer API-Daten in WordPress-Blöcken am Frontend“. In letzterem haben wir gelernt, wie man eine externe API nimmt und sie in einen Block integriert, der die abgerufenen Daten auf dem Front-End einer WordPress-Site rendert.

Die Sache ist die, dass wir dies auf eine Weise erreicht haben, die uns daran hindert, die Daten im WordPress Block Editor zu sehen. Mit anderen Worten, wir können den Block auf einer Seite einfügen, erhalten aber keine Vorschau davon. Wir sehen den Block erst, wenn er veröffentlicht ist.

Sehen wir uns noch einmal das Beispiel-Block-Plugin an, das wir im letzten Artikel erstellt haben. Nur dieses Mal werden wir das JavaScript- und React-Ökosystem von WordPress nutzen, um diese Daten auch im Back-End-Blockeditor abzurufen und zu rendern.

Wo wir aufgehört haben

Während wir das starten, Hier ist eine Demo wo wir im letzten Artikel gelandet sind, auf den Sie verweisen können. Sie haben vielleicht bemerkt, dass ich a verwendet habe render_callback -Methode im letzten Artikel, damit ich die Attribute in der PHP-Datei verwenden und den Inhalt rendern kann.

Nun, das kann in Situationen nützlich sein, in denen Sie möglicherweise eine native WordPress- oder PHP-Funktion verwenden müssen, um dynamische Blöcke zu erstellen. Wenn Sie jedoch nur das JavaScript- und React-Ökosystem (insbesondere JSX) von WordPress verwenden möchten, um das statische HTML zusammen mit den in der Datenbank gespeicherten Attributen zu rendern, müssen Sie sich nur auf das konzentrieren Edit und Save Funktionen des Block-Plugins.

  • Das Edit Die Funktion rendert den Inhalt basierend auf dem, was Sie im Blockeditor sehen möchten. Sie können hier interaktive React-Komponenten haben.
  • Das Save Die Funktion rendert den Inhalt basierend auf dem, was Sie auf dem Frontend sehen möchten. Sie können hier nicht die regulären React-Komponenten oder die Hooks haben. Es wird verwendet, um das statische HTML zurückzugeben, das zusammen mit den Attributen in Ihrer Datenbank gespeichert wird.

Das Save Funktion ist, wo wir heute abhängen. Wir können interaktive Komponenten im Front-End erstellen, aber dafür müssen wir sie manuell einschließen und außerhalb von zugreifen Save Funktion in einer Datei, wie wir es im letzten Artikel getan haben.

Ich werde also den gleichen Bereich behandeln wie im letzten Artikel, aber dieses Mal können Sie die Vorschau im Blockeditor sehen Bevor Sie veröffentlichen es im Frontend.

Die Blockrequisiten

Ich habe absichtlich auf Erklärungen zum Thema verzichtet edit die Requisiten der Funktion im letzten Artikel, da dies den Fokus vom Hauptpunkt, dem Rendern, abgelenkt hätte.

Wenn Sie aus einem React-Hintergrund kommen, werden Sie wahrscheinlich verstehen, wovon ich spreche, aber wenn Sie neu in diesem Bereich sind, würde ich empfehlen Überprüfen Sie die Komponenten und Requisiten in der React-Dokumentation.

Wenn wir die protokollieren props Objekt an die Konsole, gibt es eine Liste von WordPress-Funktionen und -Variablen zurück, die sich auf unseren Block beziehen:

Rendern von externen API-Daten in WordPress-Blöcken im Backend

Wir brauchen nur die attributes Objekt und die setAttributes Funktion, die ich von der destrukturieren werde props Objekt in meinem Code. Im letzten Artikel hatte ich den Code von RapidAPI so modifiziert, dass ich die API-Daten durch speichern kann setAttributes(). Requisiten sind nur lesbar, daher können wir sie nicht direkt ändern.

Block Props ähneln Zustandsvariablen und setState in React, aber React funktioniert auf der Client-Seite und setAttributes() wird verwendet, um die Attribute nach dem Speichern des Beitrags dauerhaft in der WordPress-Datenbank zu speichern. Also müssen wir sie retten attributes.data und nennen Sie das dann als Anfangswert für die useState() variabel.

Das edit Funktion

Ich werde den HTML-Code, den wir verwendet haben, kopieren und einfügen football-rankings.php im letzten Artikel und bearbeiten Sie ihn ein wenig, um zum JavaScript-Hintergrund zu wechseln. Erinnern Sie sich, wie wir im letzten Artikel zwei zusätzliche Dateien für das Frontend-Styling und die Skripte erstellt haben? Bei der Art und Weise, wie wir heute an die Dinge herangehen, besteht keine Notwendigkeit, diese Dateien zu erstellen. Stattdessen können wir alles in die verschieben Edit Funktion.

Vollständiger Code
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}
); })}
); } )}
)}
); }

Ich habe den React-Hook eingefügt useState() für @wordpress/element anstatt es aus der React-Bibliothek zu verwenden. Das liegt daran, dass, wenn ich auf die normale Weise laden würde, React für jeden Block heruntergeladen würde, den ich verwende. Aber wenn ich benutze @wordpress/element Es wird aus einer einzigen Quelle geladen, dh der WordPress-Schicht über React.

Dieses Mal habe ich den Code auch nicht eingepackt useEffect() sondern innerhalb einer Funktion, die nur aufgerufen wird, wenn auf eine Schaltfläche geklickt wird, sodass wir eine Live-Vorschau der abgerufenen Daten haben. Ich habe eine Zustandsvariable namens verwendet apiData die Ligatabelle bedingt zu rendern. Sobald also auf die Schaltfläche geklickt und die Daten abgerufen wurden, stelle ich ein apiData zu den neuen Daten innerhalb der fetchData() und es ist ein Rerender mit dem HTML der Fußball-Rangliste verfügbar.

Sie werden feststellen, dass die Ligatabelle verschwunden ist, sobald der Beitrag gespeichert und die Seite aktualisiert wurde. Das liegt daran, dass wir einen leeren Zustand verwenden (null) für apiDataDer Anfangswert von . Wenn der Beitrag gespeichert wird, werden die Attribute in gespeichert attributes.data Objekt und wir nennen es den Anfangswert für die useState() variabel wie folgt:

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

Das save Funktion

Wir werden fast genau dasselbe mit dem tun save funktionieren, aber ein wenig modifizieren. Beispielsweise entfällt die Schaltfläche „Daten abrufen“ am Frontend und die apiData state-Variable ist auch unnötig, da wir sie bereits in der überprüfen edit Funktion. Aber wir brauchen eine zufällige apiData Variable, die überprüft attributes.data um den JSX bedingt zu rendern, sonst werden undefinierte Fehler ausgegeben und die Benutzeroberfläche des Blockeditors wird leer.

Vollständiger Code
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}
); })}
); })}
)} ); }

Wenn Sie die modifizieren save Funktion, nachdem ein Block bereits im Blockeditor vorhanden ist, würde es einen Fehler wie diesen anzeigen:

Der Fußball-Ranglistenblock im WordPress-Blockeditor mit einer Fehlermeldung, dass der Block einen unerwarteten Fehler enthält.
Rendern von externen API-Daten in WordPress-Blöcken im Backend

Das liegt daran, dass sich das Markup im gespeicherten Inhalt vom Markup in unserem neuen unterscheidet save Funktion. Da wir uns im Entwicklungsmodus befinden, ist es einfacher, den Block von der aktuellen Seite zu entfernen und als neuen Block wieder einzufügen – auf diese Weise wird stattdessen der aktualisierte Code verwendet und die Dinge sind wieder synchron.

Diese Situation des Entfernens und erneuten Hinzufügens kann vermieden werden, wenn wir die verwendet hätten render_callback -Methode, da die Ausgabe dynamisch ist und von PHP statt von der Speicherfunktion gesteuert wird. Jede Methode hat also ihre eigenen Vor- und Nachteile.

Tom Nowell erklärt ausführlich, was in a nicht zu tun ist save Funktion in dieser Stapelüberlauf beantworten.

Styling des Blocks im Editor und im Frontend

Was das Styling betrifft, wird es fast dasselbe sein, was wir uns im letzten Artikel angesehen haben, aber mit einigen geringfügigen Änderungen, die ich in den Kommentaren erklärt habe. Ich stelle hier lediglich die vollständigen Stile bereit, da dies nur ein Proof of Concept ist und nicht etwas, das Sie kopieren und einfügen möchten (es sei denn, Sie benötigen wirklich einen Block, um Fußballranglisten in diesem Stil anzuzeigen). Und beachten Sie, dass ich immer noch SCSS verwende, das beim Build zu CSS kompiliert wird.

Editor-Stile
/* 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-Stile
/* 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;
    }
  }
}

Wir ergänzen dies src/style.scss die sich sowohl im Editor als auch im Frontend um das Styling kümmert. Ich kann die Demo-URL nicht teilen, da dafür ein Editorzugriff erforderlich wäre, aber ich habe ein Video aufgenommen, damit Sie die Demo sehen können:


Ziemlich ordentlich, oder? Jetzt haben wir einen voll funktionsfähigen Block, der nicht nur am Frontend rendert, sondern auch API-Daten abruft und direkt im Blockeditor rendert – mit einer Aktualisierungsschaltfläche zum Booten!

Aber wenn wir nehmen wollen voller Vorteil des WordPress-Block-Editors, sollten wir erwägen, einige der UI-Elemente des Blocks zuzuordnen Steuerelemente blockieren für Dinge wie das Festlegen von Farbe, Typografie und Abständen. Das ist ein netter nächster Schritt in der Lernreise zur Blockentwicklung.

Zeitstempel:

Mehr von CSS-Tricks