Gengivelse af eksterne API-data i WordPress-blokke på bagenden af ​​PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Gengivelse af eksterne API-data i WordPress-blokke på bagenden

Dette er en fortsættelse af min sidste artikel om "Gengivelse af eksterne API-data i WordPress-blokke på frontend". I den sidste lærte vi, hvordan man tager en ekstern API og integrerer den med en blok, der gengiver de hentede data på forsiden af ​​et WordPress-websted.

Sagen er, at vi opnåede dette på en måde, der forhindrer os i at se dataene i WordPress Block Editor. Med andre ord kan vi indsætte blokken på en side, men vi får ingen forhåndsvisning af den. Vi får først blokken at se, når den er offentliggjort.

Lad os gense eksemplet med blok-plugin, vi lavede i den sidste artikel. Kun denne gang vil vi gøre brug af JavaScript og React-økosystemet i WordPress til også at hente og gengive disse data i back-end Block Editor.

Hvor vi slap

Da vi starter dette, her er en demo hvor vi landede i den sidste artikel, som du kan referere til. Du har måske bemærket, at jeg brugte en render_callback metode i den sidste artikel, så jeg kan gøre brug af attributterne i PHP-filen og gengive indholdet.

Nå, det kan være nyttigt i situationer, hvor du måske skal bruge en eller anden indbygget WordPress- eller PHP-funktion til at skabe dynamiske blokke. Men hvis du kun vil bruge JavaScript og React (JSX, specifikt) økosystemet i WordPress til at gengive den statiske HTML sammen med de attributter, der er gemt i databasen, behøver du kun at fokusere på Edit , Save funktioner i blok-plugin'et.

  • Edit funktionen gengiver indholdet baseret på, hvad du vil se i Block Editor. Du kan have interaktive React-komponenter her.
  • Save funktion gengiver indholdet baseret på, hvad du vil se på frontend. Du kan ikke have de almindelige React-komponenter eller krogene her. Det bruges til at returnere den statiske HTML, der er gemt i din database sammen med attributterne.

Save funktion er, hvor vi hænger ud i dag. Vi kan oprette interaktive komponenter på front-end, men for det er vi nødt til manuelt at inkludere og få adgang til dem uden for Save funktion i en fil, som vi gjorde i den sidste artikel.

Så jeg vil dække det samme område, som vi gjorde i den sidste artikel, men denne gang kan du se forhåndsvisningen i Block Editor før du udgiver det til frontend.

Blokrekvisitterne

Jeg har med vilje udeladt enhver forklaring om edit funktions rekvisitter i den sidste artikel, fordi det ville have fjernet fokus fra hovedpunktet, gengivelsen.

Hvis du kommer fra en React-baggrund, vil du sandsynligvis forstå, hvad det er, jeg taler om, men hvis du er ny til dette, vil jeg anbefale tjekker komponenter og rekvisitter i React-dokumentationen.

Hvis vi logger props objekt til konsollen, returnerer den en liste over WordPress-funktioner og variabler relateret til vores blok:

Gengivelse af eksterne API-data i WordPress-blokke på bagenden

Vi har kun brug for attributes objektet og setAttributes funktion, som jeg vil destrukturere fra props objekt i min kode. I den sidste artikel havde jeg ændret RapidAPI's kode, så jeg kan gemme API-dataene igennem setAttributes(). Rekvisitter kan kun læses, så vi kan ikke ændre dem direkte.

Blokrekvisitter ligner tilstandsvariabler og setState i React, men React fungerer på klientsiden og setAttributes() bruges til at gemme attributterne permanent i WordPress-databasen efter at have gemt indlægget. Så det, vi skal gøre, er at gemme dem til attributes.data og kald det derefter som startværdien for useState() variabel.

edit funktion

Jeg vil kopiere og indsætte HTML-koden, som vi brugte i football-rankings.php i den sidste artikel og rediger den lidt for at skifte til JavaScript-baggrunden. Kan du huske, hvordan vi oprettede to ekstra filer i den sidste artikel til frontend-styling og scripts? Med den måde, vi griber tingene an på i dag, er der ingen grund til at oprette disse filer. I stedet kan vi flytte det hele til Edit funktion.

Fuld 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 inkluderet React krogen useState() fra @wordpress/element i stedet for at bruge det fra React-biblioteket. Det er fordi, hvis jeg skulle indlæse den almindelige måde, ville den downloade React for hver blok, jeg bruger. Men hvis jeg bruger @wordpress/element det indlæses fra en enkelt kilde, dvs. WordPress-laget oven på React.

Denne gang har jeg heller ikke pakket koden ind useEffect() men inde i en funktion, der kun kaldes, når man klikker på en knap, så vi har et live preview af de hentede data. Jeg har brugt en tilstandsvariabel kaldet apiData at gøre ligatabellen betinget. Så når først der er klikket på knappen, og dataene er hentet, indstiller jeg apiData til de nye data inde i fetchData() og der er en gengivelse med HTML fra fodboldranglisten tilgængelig.

Du vil bemærke, at når indlægget er gemt og siden er opdateret, er ligatabellen væk. Det er fordi vi bruger en tom tilstand (null) til apiData's begyndelsesværdi. Når indlægget gemmes, gemmes attributterne til attributes.data objekt, og vi kalder det som startværdien for useState() variabel som denne:

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

save funktion

Vi kommer til at gøre næsten det samme med save funktion, men modificer den lidt. For eksempel er der ikke behov for knappen "Hent data" på frontenden og apiData tilstandsvariabel er også unødvendig, fordi vi allerede tjekker den i edit fungere. Men vi har brug for et tilfældigt apiData variabel, der tjekker for attributes.data for at betinget gengive JSX, ellers vil det kaste udefinerede fejl, og Block Editor UI bliver tom.

Fuld 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 ændrer save funktion efter at en blok allerede er til stede i Block Editor, vil den vise en fejl som denne:

Fodboldranglisten blokerer i WordPress-blokeditoren med en fejlmeddelelse om, at blokken indeholder en uventet fejl.
Gengivelse af eksterne API-data i WordPress-blokke på bagenden

Det skyldes, at opmærkningen i det gemte indhold er forskellig fra opmærkningen i vores nye save fungere. Da vi er i udviklingstilstand, er det nemmere at fjerne bocken fra den aktuelle side og genindsætte den som en ny blok - på den måde bruges den opdaterede kode i stedet, og tingene er tilbage i sync.

Denne situation med at fjerne det og tilføje det igen kan undgås, hvis vi havde brugt render_callback metode, da outputtet er dynamisk og styret af PHP i stedet for gem-funktionen. Så hver metode har sine egne fordele og ulemper.

Tom Nowell giver en grundig forklaring på, hvad man ikke skal gøre i en save funktion i denne Stack Overflow besvare.

Styling af blokken i editoren og frontend

Med hensyn til stylingen kommer det til at være næsten det samme, som vi så på i den sidste artikel, men med nogle mindre ændringer, som jeg har forklaret i kommentarerne. Jeg giver blot de fulde stilarter her, da dette kun er et bevis på konceptet snarere end noget, du vil kopiere og indsætte (medmindre du virkelig har brug for en blok for at vise fodboldranglister, der er stylet som dette). Og bemærk, at jeg stadig bruger SCSS, der kompilerer til CSS på build.

Editor stilarter
/* 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 stilarter
/* 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 tilføjer dette til src/style.scss som tager sig af stylingen i både editor og frontend. Jeg vil ikke være i stand til at dele demo-URL'en, da den ville kræve redaktøradgang, men jeg har en video optaget, så du kan se demoen:


Ret pænt, ikke? Nu har vi en fuldt fungerende blok, der ikke kun gengiver på frontend, men også henter API-data og gengiver lige der i Block Editor - med en opdateringsknap til at starte!

Men hvis vi vil tage fuld fordel af WordPress Block Editor, bør vi overveje at kortlægge nogle af blokkens UI-elementer til blok kontrol til ting som indstilling af farve, typografi og mellemrum. Det er et godt næste skridt i blokudviklingslæringsrejsen.

Tidsstempel:

Mere fra CSS-tricks