Gjengivelse av eksterne API-data i WordPress-blokker på baksiden av PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Gjengivelse av eksterne API-data i WordPress-blokker på baksiden

Dette er en fortsettelse av min siste artikkel om "Å gjengi eksterne API-data i WordPress-blokker på grensesnittet". I den siste lærte vi å ta en ekstern API og integrere den med en blokk som gjengir de hentede dataene på frontenden av et WordPress-nettsted.

Saken er at vi oppnådde dette på en måte som hindrer oss i å se dataene i WordPress Block Editor. Med andre ord, vi kan sette inn blokken på en side, men vi får ingen forhåndsvisning av den. Vi får først se blokken når den er publisert.

La oss se på eksempelblokkpluginen vi laget i forrige artikkel. Bare denne gangen skal vi bruke JavaScript og React-økosystemet til WordPress for å hente og gjengi disse dataene også i back-end Block Editor.

Der vi slapp

Når vi starter dette, her er en demo hvor vi landet i den siste artikkelen som du kan referere til. Du har kanskje lagt merke til at jeg brukte en render_callback metoden i den siste artikkelen slik at jeg kan bruke attributtene i PHP-filen og gjengi innholdet.

Vel, det kan være nyttig i situasjoner der du kanskje må bruke en innfødt WordPress- eller PHP-funksjon for å lage dynamiske blokker. Men hvis du bare vil bruke JavaScript og React (JSX, spesifikt) økosystemet til WordPress for å gjengi statisk HTML sammen med attributtene som er lagret i databasen, trenger du bare å fokusere på Edit og Save funksjonene til blokkeringspluginen.

  • De Edit funksjonen gjengir innholdet basert på hva du ønsker å se i Block Editor. Du kan ha interaktive React-komponenter her.
  • De Save funksjonen gjengir innholdet basert på hva du vil se på grensesnittet. Du kan ikke ha de vanlige React-komponentene eller krokene her. Den brukes til å returnere den statiske HTML-koden som er lagret i databasen sammen med attributtene.

De Save funksjonen er der vi henger ut i dag. Vi kan lage interaktive komponenter på front-end, men for det må vi manuelt inkludere og få tilgang til dem utenfor Save funksjon i en fil som vi gjorde i forrige artikkel.

Så, jeg skal dekke det samme området som vi gjorde i forrige artikkel, men denne gangen kan du se forhåndsvisningen i Block Editor før du du publiserer den til frontend.

Blokkrekvisittene

Jeg har med vilje utelatt noen forklaringer om edit funksjonens rekvisitter i den siste artikkelen fordi det ville ha fjernet fokuset fra hovedpoenget, gjengivelsen.

Hvis du kommer fra en React-bakgrunn, vil du sannsynligvis forstå hva jeg snakker om, men hvis du er ny på dette, vil jeg anbefale sjekke ut komponenter og rekvisitter i React-dokumentasjonen.

Hvis vi logger props objekt til konsollen, returnerer den en liste over WordPress-funksjoner og variabler relatert til blokken vår:

Gjengivelse av eksterne API-data i WordPress-blokker på baksiden

Vi trenger bare attributes objektet og setAttributes funksjon som jeg skal destrukturere fra props objekt i koden min. I den siste artikkelen hadde jeg modifisert RapidAPIs kode slik at jeg kan lagre API-dataene gjennom setAttributes(). Rekvisitter er kun lesbare, så vi kan ikke endre dem direkte.

Blokkrekvisitter ligner på tilstandsvariabler og setState i React, men React fungerer på klientsiden og setAttributes() brukes til å lagre attributtene permanent i WordPress-databasen etter lagring av innlegget. Så det vi må gjøre er å redde dem til attributes.data og kall det deretter som startverdien for useState() variabel.

De edit funksjon

Jeg skal kopiere og lime inn HTML-koden som vi brukte i football-rankings.php i den siste artikkelen og rediger den litt for å skifte til JavaScript-bakgrunnen. Husker du hvordan vi opprettet to ekstra filer i den siste artikkelen for frontend-styling og skript? Med måten vi nærmer oss ting i dag, er det ikke nødvendig å lage disse filene. I stedet kan vi flytte alt til Edit funksjon.

Full kode
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}
); })}
); } )}
)}
); }

Jeg har inkludert React-kroken useState() fra @wordpress/element i stedet for å bruke den fra React-biblioteket. Det er fordi hvis jeg skulle laste den vanlige måten, ville den laste ned React for hver blokk jeg bruker. Men hvis jeg bruker @wordpress/element det laster fra en enkelt kilde, dvs. WordPress-laget på toppen av React.

Denne gangen har jeg heller ikke pakket inn koden useEffect() men inne i en funksjon som kalles kun når du klikker på en knapp slik at vi har en live forhåndsvisning av de hentede dataene. Jeg har brukt en tilstandsvariabel kalt apiData å gjengi ligatabellen betinget. Så når knappen er klikket og dataene er hentet, setter jeg apiData til de nye dataene i fetchData() og det er en gjengivelse med HTML-koden til fotballrankingstabellen tilgjengelig.

Du vil legge merke til at når innlegget er lagret og siden er oppdatert, er ligatabellen borte. Det er fordi vi bruker en tom tilstand (null) for apiDatasin opprinnelige verdi. Når innlegget lagres, lagres attributtene til attributes.data objekt og vi kaller det som startverdien for useState() variabel som dette:

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

De save funksjon

Vi kommer til å gjøre nesten det samme med save funksjon, men endre den litt. For eksempel er det ikke behov for "Hent data"-knappen på fronten, og apiData tilstandsvariabel er også unødvendig fordi vi allerede sjekker den i edit funksjon. Men vi trenger en tilfeldighet apiData variabel som sjekker etter attributes.data for å betinget gjengi JSX, ellers vil det gi udefinerte feil og Block Editor-grensesnittet blir tomt.

Full kode
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}
); })}
); })}
)} ); }

Hvis du endrer save funksjon etter at en blokk allerede er til stede i blokkredigeringsprogrammet, vil den vise en feil som dette:

Fotballrankingen blokkerer i WordPress-blokkeditoren med en feilmelding om at blokken inneholder en uventet feil.
Gjengivelse av eksterne API-data i WordPress-blokker på baksiden

Det er fordi markeringen i det lagrede innholdet er forskjellig fra markeringen i vår nye save funksjon. Siden vi er i utviklingsmodus, er det lettere å fjerne blokken fra den gjeldende siden og sette den inn på nytt som en ny blokk – på den måten brukes den oppdaterte koden i stedet og ting er tilbake synkronisert.

Denne situasjonen med å fjerne den og legge den til igjen kan unngås hvis vi hadde brukt render_callback metode siden utgangen er dynamisk og kontrollert av PHP i stedet for lagringsfunksjonen. Så hver metode har sine egne fordeler og ulemper.

Tom Nowell gir en grundig forklaring på hva du ikke skal gjøre i en save fungere i denne Stack Overflow besvare.

Styling av blokken i editoren og frontend

Når det gjelder stylingen, kommer det til å være nesten det samme som vi så på i forrige artikkel, men med noen mindre endringer som jeg har forklart i kommentarfeltet. Jeg gir bare de fullstendige stilene her siden dette bare er et bevis på konseptet i stedet for noe du vil kopiere og lime inn (med mindre du virkelig trenger en blokk for å vise fotballrankinger stilt akkurat som dette). Og merk at jeg fortsatt bruker SCSS som kompilerer til CSS på build.

Redaktørstiler
/* 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 stiler
/* 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;
    }
  }
}

Vi legger dette til src/style.scss som tar seg av stylingen i både editoren og frontend. Jeg vil ikke være i stand til å dele demo-URL siden den vil kreve redaktørtilgang, men jeg har tatt opp en video slik at du kan se demoen:


Ganske ryddig, ikke sant? Nå har vi en fullt fungerende blokk som ikke bare gjengir på frontend, men også henter API-data og gjengir rett der i Block Editor - med en oppdateringsknapp for å starte opp!

Men hvis vi vil ta fullt Fordelen med WordPress Block Editor, bør vi vurdere å kartlegge noen av blokkens brukergrensesnittelementer til blokkkontroller for ting som å angi farge, typografi og avstand. Det er et fint neste steg i læringsreisen for blokkutvikling.

Tidstempel:

Mer fra CSS triks