Redarea datelor API externe în blocuri WordPress pe back-end PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Redarea datelor API externe în blocuri WordPress din back-end

Aceasta este o continuare a ultimului articol despre „Redarea datelor API externe în blocuri WordPress pe front end”. În ultimul, am învățat cum să luăm un API extern și să îl integrăm cu un bloc care redă datele preluate pe front-end-ul unui site WordPress.

Chestia este că am realizat acest lucru într-un mod care ne împiedică să vedem datele în Editorul de blocuri WordPress. Cu alte cuvinte, putem insera blocul pe o pagină, dar nu obținem o previzualizare a acestuia. Putem vedea blocul doar când este publicat.

Să revedem exemplul de plugin de bloc pe care l-am creat în ultimul articol. Numai de această dată, vom folosi ecosistemul JavaScript și React al WordPress pentru a prelua și reda acele date și în editorul de blocuri back-end.

De unde am plecat

Când începem asta, iată un demo unde am aterizat în ultimul articol pe care îl puteți referi. Poate ați observat că am folosit a render_callback metoda din ultimul articol, astfel încât să pot folosi atributele din fișierul PHP și să reda conținutul.

Ei bine, asta poate fi util în situațiile în care ar putea fi necesar să utilizați o funcție nativă WordPress sau PHP pentru a crea blocuri dinamice. Dar dacă doriți să utilizați doar ecosistemul JavaScript și React (JSX, în special) al WordPress pentru a reda HTML-ul static împreună cu atributele stocate în baza de date, trebuie să vă concentrați doar pe Edit și Save funcțiile plugin-ului bloc.

  • Edit funcția redă conținutul pe baza a ceea ce doriți să vedeți în Editorul de blocuri. Puteți avea componente interactive React aici.
  • Save funcția redă conținutul pe baza a ceea ce doriți să vedeți pe front end. Nu puteți avea aici componentele obișnuite React sau cârligele. Este folosit pentru a returna codul HTML static care este salvat în baza de date împreună cu atributele.

Save Funcția este locul în care petrecem azi. Putem crea componente interactive pe front-end, dar pentru asta trebuie să le includem și să le accesăm manual în afara Save funcția într-un fișier așa cum am făcut-o în ultimul articol.

Deci, voi acoperi același teren pe care l-am făcut în ultimul articol, dar de data aceasta puteți vedea previzualizarea în Editorul de blocuri înainte îl publicați pe front-end.

Recuzita blocului

Am omis în mod intenționat orice explicație despre edit elementele de recuzită ale funcției din ultimul articol, deoarece asta ar fi scos accentul de pe punctul principal, randarea.

Dacă vii dintr-un mediu React, probabil vei înțelege despre ce vorbesc, dar dacă ești nou în acest domeniu, aș recomanda verificarea componentelor și elementelor de recuzită în documentația React.

Dacă înregistrăm props obiect la consolă, returnează o listă de funcții și variabile WordPress legate de blocul nostru:

Redarea datelor API externe în blocuri WordPress din back-end

Avem nevoie doar de attributes obiect şi cel setAttributes funcția pe care o voi destructura din props obiect din codul meu. În ultimul articol, am modificat codul RapidAPI, astfel încât să pot stoca datele API setAttributes(). Recuzitele sunt doar lizibile, așa că nu le putem modifica direct.

Blocurile de recuzită sunt similare cu variabilele de stare și setState în React, dar React funcționează pe partea clientului și setAttributes() este folosit pentru a stoca permanent atributele în baza de date WordPress după salvarea postării. Deci, ceea ce trebuie să facem este să-i salvăm attributes.data și apoi numiți asta ca valoare inițială pentru useState() variabilă.

edit funcţie

Voi copia și lipi codul HTML pe care l-am folosit football-rankings.php în ultimul articol și editați-l puțin pentru a trece la fundalul JavaScript. Vă amintiți cum am creat două fișiere suplimentare în ultimul articol pentru stilul și scripturile frontale? Cu modul în care abordăm lucrurile astăzi, nu este nevoie să creăm acele fișiere. În schimb, putem muta totul în Edit Funcția.

Cod complet
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}
); })}
); } )}
)}
); }

Am inclus cârligul React useState() din @wordpress/element mai degrabă decât să-l folosească din biblioteca React. Asta pentru că, dacă ar fi să încarc modul obișnuit, ar descărca React pentru fiecare bloc pe care îl folosesc. Dar dacă folosesc @wordpress/element se încarcă dintr-o singură sursă, adică stratul WordPress de deasupra lui React.

De data aceasta, nici nu am împachetat codul înăuntru useEffect() dar în interiorul unei funcții care este apelată doar când faceți clic pe un buton, astfel încât să avem o previzualizare live a datelor preluate. Am folosit o variabilă de stare numită apiData pentru a reda tabelul ligii în mod condiționat. Deci, odată ce se face clic pe butonul și datele sunt preluate, setez apiData la noile date din interiorul fetchData() și există o redare cu HTML-ul tabelului de clasament al fotbalului disponibil.

Veți observa că odată ce postarea este salvată și pagina este reîmprospătată, clasamentul a dispărut. Asta pentru că folosim o stare goală (null) pentru apiDatavaloarea initiala a lui. Când postarea se salvează, atributele sunt salvate în attributes.data obiect și îl numim ca valoare inițială pentru useState() variabila astfel:

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

save funcţie

Vom face aproape același lucru cu save funcția, dar modificați-o puțin. De exemplu, nu este nevoie de butonul „Preluare date” de pe partea frontală, iar butonul apiData variabila de stat este, de asemenea, inutilă, deoarece o verificăm deja în edit funcţie. Dar avem nevoie de o întâmplare apiData variabilă care verifică attributes.data pentru a reda condiționat JSX-ul, altfel va arunca erori nedefinite și interfața de utilizare a editorului de blocuri va rămâne goală.

Cod complet
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}
); })}
); })}
)} ); }

Dacă modificați save după ce un bloc este deja prezent în Editorul de blocuri, ar afișa o eroare ca aceasta:

Clasamentul fotbalistic se blochează în Editorul de blocuri WordPress cu un mesaj de eroare că blocul conține o eroare neașteptată.
Redarea datelor API externe în blocuri WordPress din back-end

Acest lucru se datorează faptului că marcajul din conținutul salvat este diferit de marcajul din noul nostru save funcţie. Deoarece ne aflăm în modul de dezvoltare, este mai ușor să scoatem bock-ul din pagina curentă și să îl reinserăm ca bloc nou - în acest fel, codul actualizat este folosit și lucrurile sunt din nou sincronizate.

Această situație de a-l elimina și de a-l adăuga din nou poate fi evitată dacă am fi folosit render_callback metoda deoarece ieșirea este dinamică și controlată de PHP în loc de funcția de salvare. Deci, fiecare metodă are propriile avantaje și dezavantaje.

Tom Nowell oferă o explicație amănunțită despre ce să nu faci într-un save funcția în acest Stack Overflow răspunde.

Stilizarea blocului în editor și front-end

În ceea ce privește stilul, va fi aproape același lucru la care ne-am uitat în ultimul articol, dar cu câteva modificări minore pe care le-am explicat în comentarii. Vă ofer doar stilurile complete aici, deoarece aceasta este doar o dovadă a conceptului, mai degrabă decât ceva ce doriți să copiați și lipiți (cu excepția cazului în care aveți într-adevăr nevoie de un bloc pentru a afișa clasamentele de fotbal în stilul acesta). Și rețineți că încă folosesc SCSS care se compilează în CSS la build.

Stiluri de editor
/* 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);
    }
  }
}
Stiluri front-end
/* 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;
    }
  }
}

Adăugăm asta la src/style.scss care se ocupă de stilul atât în ​​editor, cât și în frontend. Nu voi putea partaja adresa URL a demonstrației, deoarece ar necesita acces la editor, dar am un videoclip înregistrat pentru ca tu să vezi demonstrația:


Destul de îngrijit, nu? Acum avem un bloc pe deplin funcțional care nu numai că se redă pe front-end, dar preia și datele API și se redă chiar acolo în Editorul de blocuri - cu un buton de reîmprospătare pentru a porni!

Dar dacă vrem să luăm Complet avantajul Editorului de blocuri WordPress, ar trebui să luăm în considerare maparea unora dintre elementele UI ale blocului către bloc de controale pentru lucruri precum setarea culorii, tipografiei și spațierea. Acesta este un următor pas frumos în călătoria de învățare a dezvoltării blocurilor.

Timestamp-ul:

Mai mult de la CSS Trucuri