Externe API-gegevens weergeven in WordPress-blokken op de backend PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Externe API-gegevens weergeven in WordPress-blokken aan de achterkant

Dit is een vervolg op mijn laatste artikel over "Externe API-gegevens weergeven in WordPress-blokken aan de voorkant". In die laatste leerden we hoe we een externe API konden nemen en deze konden integreren met een blok dat de opgehaalde gegevens aan de voorkant van een WordPress-site weergeeft.

Het punt is dat we dit hebben bereikt op een manier die voorkomt dat we de gegevens in de WordPress Block Editor zien. Met andere woorden, we kunnen het blok op een pagina invoegen, maar we krijgen er geen voorbeeld van. We krijgen het blok pas te zien als het is gepubliceerd.

Laten we nog eens kijken naar de voorbeeldblokplug-in die we in het vorige artikel hebben gemaakt. Alleen gaan we deze keer gebruik maken van het JavaScript- en React-ecosysteem van WordPress om die gegevens ook in de back-end Block Editor op te halen en weer te geven.

Waar waren we gebleven

Terwijl we dit aftrappen, hier is een demo waar we zijn beland in het laatste artikel waarnaar u kunt verwijzen. Je hebt misschien gemerkt dat ik een render_callback methode in het laatste artikel zodat ik gebruik kan maken van de attributen in het PHP-bestand en de inhoud kan renderen.

Nou, dat kan handig zijn in situaties waarin je misschien een native WordPress- of PHP-functie moet gebruiken om dynamische blokken te maken. Maar als u alleen gebruik wilt maken van het JavaScript en React (JSX, specifiek) ecosysteem van WordPress om de statische HTML weer te geven samen met de attributen die in de database zijn opgeslagen, hoeft u zich alleen te concentreren op de Edit en Save functies van de blokplug-in.

  • De Edit functie rendert de inhoud op basis van wat u wilt zien in de Block Editor. U kunt hier interactieve React-componenten hebben.
  • De Save functie geeft de inhoud weer op basis van wat u aan de voorkant wilt zien. Je kunt hier niet de reguliere React-componenten of de haken hebben. Het wordt gebruikt om de statische HTML te retourneren die samen met de attributen in uw database is opgeslagen.

De Save functie is waar we vandaag rondhangen. We kunnen interactieve componenten aan de front-end maken, maar daarvoor moeten we ze handmatig opnemen en openen buiten de Save functioneren in een bestand zoals we deden in het vorige artikel.

Dus ik ga hetzelfde onderwerp behandelen als in het vorige artikel, maar deze keer kun je de preview zien in de Block Editor vaardigheden je publiceert het naar de front-end.

De blokrekwisieten

Ik heb met opzet alle uitleg over de weggelaten edit de rekwisieten van de functie in het laatste artikel, omdat dat de focus zou hebben weggenomen van het belangrijkste punt, de weergave.

Als je uit een React-achtergrond komt, zul je waarschijnlijk begrijpen waar ik het over heb, maar als dit nieuw voor je is, zou ik aanraden componenten en rekwisieten bekijken in de React-documentatie.

Als we de props object naar de console, retourneert het een lijst met WordPress-functies en variabelen met betrekking tot ons blok:

Externe API-gegevens weergeven in WordPress-blokken aan de achterkant

We hebben alleen de nodig attributes object en de setAttributes functie die ik ga destructureren van de props object in mijn code. In het laatste artikel had ik de code van RapidAPI aangepast zodat ik de API-gegevens kan opslaan via setAttributes(). Props zijn alleen leesbaar, dus we kunnen ze niet direct wijzigen.

Blokrekwisieten zijn vergelijkbaar met toestandsvariabelen en setState in React, maar React werkt aan de clientzijde en setAttributes() wordt gebruikt om de attributen permanent op te slaan in de WordPress-database na het opslaan van het bericht. Dus wat we moeten doen is ze opslaan om attributes.data en noem dat dan als de beginwaarde voor de useState() variabel.

De edit functie

Ik ga de HTML-code kopiëren en plakken die we hebben gebruikt in football-rankings.php in het laatste artikel en bewerk het een beetje om naar de JavaScript-achtergrond te gaan. Weet je nog hoe we in het laatste artikel twee extra bestanden hebben gemaakt voor de front-end-styling en scripts? Met de manier waarop we de dingen tegenwoordig benaderen, is het niet nodig om die bestanden te maken. In plaats daarvan kunnen we alles verplaatsen naar de Edit functie.

Volledige 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}
); })}
); } )}
)}
); }

Ik heb de React hook toegevoegd useState() oppompen van @wordpress/element in plaats van het uit de React-bibliotheek te gebruiken. Dat komt omdat als ik op de normale manier zou laden, het React zou downloaden voor elk blok dat ik gebruik. Maar als ik gebruik @wordpress/element het laadt vanuit een enkele bron, dat wil zeggen, de WordPress-laag bovenop React.

Deze keer heb ik de code ook niet ingepakt useEffect() maar binnen een functie die alleen wordt aangeroepen wanneer op een knop wordt geklikt, zodat we een live voorbeeld hebben van de opgehaalde gegevens. Ik heb een toestandsvariabele gebruikt met de naam apiData om de ranglijst voorwaardelijk te maken. Dus zodra op de knop is geklikt en de gegevens zijn opgehaald, ben ik aan het instellen apiData naar de nieuwe gegevens in de fetchData() en er is een rerender met de HTML van de voetbalranglijst beschikbaar.

U zult merken dat zodra het bericht is opgeslagen en de pagina is vernieuwd, de ranglijst is verdwenen. Dat komt omdat we een lege toestand gebruiken (null) voor apiDatade beginwaarde. Wanneer het bericht wordt opgeslagen, worden de kenmerken opgeslagen in de attributes.data object en we noemen het als de beginwaarde voor de useState() variabele als deze:

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

De save functie

We gaan bijna precies hetzelfde doen met de save functie, maar pas het een beetje aan. Er is bijvoorbeeld geen behoefte aan de knop "Gegevens ophalen" aan de voorkant, en de apiData state variabele is ook niet nodig omdat we het al controleren in de edit functie. Maar we hebben wel een willekeurige nodig apiData variabele die controleert op attributes.data om de JSX voorwaardelijk weer te geven, anders worden er ongedefinieerde fouten gegenereerd en wordt de gebruikersinterface van de Block Editor leeg.

Volledige 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}
); })}
); })}
)} ); }

Als u de wijzigt save functie nadat een blok al aanwezig is in de Block Editor, zou het een fout als deze tonen:

Het voetbalranglijstblok in de WordPress-blokeditor met een foutmelding dat het blok een onverwachte fout bevat.
Externe API-gegevens weergeven in WordPress-blokken aan de achterkant

Dat komt omdat de opmaak in de opgeslagen inhoud anders is dan de opmaak in onze nieuwe save functie. Omdat we ons in de ontwikkelingsmodus bevinden, is het gemakkelijker om de bock van de huidige pagina te verwijderen en opnieuw in te voegen als een nieuw blok - op die manier wordt in plaats daarvan de bijgewerkte code gebruikt en zijn de zaken weer gesynchroniseerd.

Deze situatie van verwijderen en opnieuw toevoegen kan worden vermeden als we de hadden gebruikt render_callback methode omdat de uitvoer dynamisch is en wordt bestuurd door PHP in plaats van de opslagfunctie. Elke methode heeft dus zijn eigen voor- en nadelen.

Tom Nowell geeft een grondige uitleg over wat je niet moet doen in a save functie in deze Stack Overflow beantwoorden.

Het blok stylen in de editor en de front-end

Wat betreft de styling, het zal bijna hetzelfde zijn als waar we in het vorige artikel naar hebben gekeken, maar met enkele kleine wijzigingen die ik in de opmerkingen heb uitgelegd. Ik geef hier alleen de volledige stijlen, omdat dit slechts een proof of concept is en niet iets dat je wilt kopiëren en plakken (tenzij je echt een blok nodig hebt voor het weergeven van voetbalranglijsten die net als deze zijn gestyled). En merk op dat ik nog steeds SCSS gebruik dat compileert naar CSS bij het bouwen.

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

We voegen dit toe aan src/style.scss die zorgt voor de styling in zowel de editor als de frontend. Ik kan de demo-URL niet delen omdat hiervoor editortoegang nodig is, maar ik heb een video voor je opgenomen om de demo te zien:


Best netjes toch? Nu hebben we een volledig functionerend blok dat niet alleen aan de voorkant wordt weergegeven, maar ook API-gegevens ophaalt en daar in de Block Editor wordt weergegeven - met een vernieuwingsknop om op te starten!

Maar als we willen nemen vol voordeel van de WordPress Block Editor, zouden we moeten overwegen om enkele van de UI-elementen van het blok toe te wijzen aan: besturingselementen blokkeren voor zaken als het instellen van kleur, typografie en spatiëring. Dat is een mooie volgende stap in het leertraject blokontwikkeling.

Tijdstempel:

Meer van CSS-trucs