Tämä on jatkoa edelliselle artikkelilleni "Ulkoisten API-tietojen renderöiminen WordPress-lohkoissa käyttöliittymässä". Viimeisessä opimme ottamaan ulkoisen API:n ja integroimaan sen lohkoon, joka renderöi haetut tiedot WordPress-sivuston etupäässä.
Asia on, että saavutimme tämän tavalla, joka estää meitä näkemästä tietoja WordPress Block Editorissa. Toisin sanoen voimme lisätä lohkon sivulle, mutta emme saa esikatselua siitä. Näemme lohkon vasta, kun se julkaistaan.
Katsotaanpa uudelleen esimerkkilohkolaajennusta, jonka teimme edellisessä artikkelissa. Vain tällä kertaa aiomme hyödyntää WordPressin JavaScript- ja React-ekosysteemiä noutaaksemme ja hahmontaaksemme tiedot myös lohkoeditorissa.
Siitä mihin jäimme
Kun aloitamme tämän, tässä demo mihin päädyimme viimeiseen artikkeliin, johon voit viitata. Olet ehkä huomannut, että käytin a render_callback
-menetelmää viimeisessä artikkelissa, jotta voin käyttää PHP-tiedoston attribuutteja ja hahmontaa sisällön.
No, siitä voi olla hyötyä tilanteissa, joissa saatat joutua käyttämään jotain natiivia WordPress- tai PHP-toimintoa dynaamisten lohkojen luomiseen. Mutta jos haluat käyttää vain WordPressin JavaScript- ja React-ekosysteemiä (erityisesti JSX) staattisen HTML:n hahmontamiseen tietokantaan tallennettujen attribuuttien kanssa, sinun tarvitsee vain keskittyä Edit
ja Save
lohkolaajennuksen toiminnot.
- -
Edit
toiminto renderöi sisällön sen perusteella, mitä haluat nähdä lohkoeditorissa. Täällä voi olla interaktiivisia React-komponentteja. - -
Save
toiminto renderöi sisällön sen perusteella, mitä haluat nähdä käyttöliittymässä. Täällä ei voi olla tavallisia React-komponentteja tai koukkuja. Sitä käytetään palauttamaan staattinen HTML, joka on tallennettu tietokantaan attribuuttien kanssa.
- Save
toiminto on paikka, jossa vietämme aikaa tänään. Voimme luoda interaktiivisia komponentteja käyttöliittymään, mutta sitä varten meidän on sisällytettävä ne manuaalisesti ja käytettävä niitä käyttöliittymän ulkopuolella Save
toimii tiedostossa, kuten teimme edellisessä artikkelissa.
Joten aion kattaa saman alueen kuin teimme viime artikkelissa, mutta tällä kertaa voit nähdä esikatselun lohkoeditorissa ennen julkaiset sen etupäässä.
Lohkon rekvisiitta
Jätin tarkoituksella pois kaikki selitykset aiheesta edit
funktion rekvisiitta viimeisessä artikkelissa, koska se olisi poistanut huomion pääkohdasta, renderöinnista.
Jos olet kotoisin React-taustasta, ymmärrät todennäköisesti mistä puhun, mutta jos olet uusi tässä, suosittelen tarkista komponentit ja rekvisiitta Reactin dokumentaatiosta.
Jos kirjaamme props
objekti konsoliin, se palauttaa luettelon lohkoomme liittyvistä WordPress-funktioista ja muuttujista:
Tarvitsemme vain attributes
esine ja setAttributes
toiminto, jonka aion tuhota props
objekti koodissani. Edellisessä artikkelissa olin muokannut RapidAPI:n koodia, jotta voin tallentaa API-tiedot setAttributes()
. Rekvisiitta on vain luettavissa, joten emme voi muokata niitä suoraan.
Lohkon rekvisiitta on samanlainen kuin tilamuuttujat ja setState
Reactissa, mutta React toimii asiakaspuolella ja setAttributes()
käytetään määritteiden tallentamiseen pysyvästi WordPress-tietokantaan viestin tallentamisen jälkeen. Joten meidän on pelastettava heidät attributes.data
ja kutsu sitä sitten alkuarvona useState()
muuttuja.
edit
toiminto
- Aion kopioida ja liittää käyttämämme HTML-koodin football-rankings.php
viimeisessä artikkelissa ja muokkaa sitä hieman siirtyäksesi JavaScript-taustalle. Muistatko, kuinka loimme kaksi lisätiedostoa edellisessä artikkelissa käyttöliittymän tyyliä ja komentosarjoja varten? Nykyisen lähestymistavan vuoksi näitä tiedostoja ei tarvitse luoda. Sen sijaan voimme siirtää sen kaiken Edit
toiminto.
Täysi koodi
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}
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => {
return (
{result}
);
})}
);
}
)}
)}
);
}
Olen lisännyt React-koukun useState()
alkaen @wordpress/element
sen sijaan, että käytät sitä React-kirjastosta. Tämä johtuu siitä, että jos lataan tavallisella tavalla, se lataa Reactin jokaiselle käyttämälleni lohkolle. Mutta jos käytän @wordpress/element
se latautuu yhdestä lähteestä, eli Reactin päällä olevasta WordPress-tasosta.
Tällä kertaa en ole myöskään käärinyt koodia sisään useEffect()
mutta funktion sisällä, jota kutsutaan vain napsauttamalla painiketta, jotta meillä on suora esikatselu haetuista tiedoista. Olen käyttänyt tilamuuttujaa nimeltä apiData
tehdä liigataulukko ehdollisena. Joten, kun painiketta napsautetaan ja tiedot on haettu, teen asetusta apiData
sisällä oleviin uusiin tietoihin fetchData()
ja saatavilla on uudelleenrenderöinti jalkapallon rankingtaulukon HTML-koodilla.
Huomaat, että kun viesti on tallennettu ja sivu päivitetty, sarjataulukko on poissa. Tämä johtuu siitä, että käytämme tyhjää tilaa (null
) varten apiData
alkuarvo. Kun viesti tallennetaan, määritteet tallennetaan hakemistoon attributes.data
objekti ja kutsumme sitä alkuarvoksi useState()
muuttuja näin:
const [apiData, setApiData] = useState(attributes.data);
save
toiminto
- Aiomme tehdä melkein saman asian kanssa save
toimintoa, mutta muokkaa sitä hieman. Ei esimerkiksi tarvita "Hae tiedot" -painiketta käyttöliittymässä ja apiData
tilamuuttuja on myös tarpeeton, koska olemme jo tarkistamassa sitä edit
toiminto. Mutta me tarvitsemme satunnaisen apiData
muuttuja, joka tarkistaa attributes.data
Ehdollisesti renderöidä JSX tai muuten se aiheuttaa määrittelemättömiä virheitä ja Block Editorin käyttöliittymä tyhjenee.
Täysi koodi
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}
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => {
return (
{result}
);
})}
);
})}
)}
);
}
Jos muutat save
toiminto sen jälkeen, kun lohko on jo olemassa lohkoeditorissa, se näyttäisi seuraavanlaisen virheen:
Tämä johtuu siitä, että tallennetun sisällön merkinnät eroavat uudessa sisällöstämme save
toiminto. Koska olemme kehitystilassa, on helpompaa poistaa bock nykyiseltä sivulta ja lisätä se uudelleen uutena lohkona - näin päivitetty koodi käytetään sen sijaan ja asiat ovat taas synkronoituina.
Tämä tilanne, jossa se poistetaan ja lisätään uudelleen, voidaan välttää, jos olisimme käyttäneet render_callback
menetelmä, koska tulos on dynaaminen ja PHP ohjaa sitä tallennustoiminnon sijaan. Jokaisella menetelmällä on siis omat etunsa ja haittansa.
Tom Nowell antaa perusteellisen selvityksen siitä, mitä ei saa tehdä a save
toiminto tämä Stack Overflow vastaus.
Lohkon muotoilu editorissa ja etuosassa
Mitä tulee tyyliin, se on melkein sama asia, jota tarkastelimme viime artikkelissa, mutta pienin muutoksin, jotka olen selittänyt kommenteissa. Tarjoan tässä vain täydelliset tyylit, koska tämä on vain todiste konseptista sen sijaan, että haluat kopioida ja liittää (ellet todella tarvitse lohkoa näyttääksesi jalkapallosijoituksia juuri tällä tavalla). Huomaa, että käytän edelleen SCSS:ää, joka käännetään CSS:ksi koontivaiheessa.
Editorin tyylit
/* 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);
}
}
}
Etupäätyylit
/* 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;
}
}
}
Lisäämme tämän src/style.scss
joka huolehtii sekä editorin että käyttöliittymän tyylistä. En voi jakaa demon URL-osoitetta, koska se vaatisi editorin pääsyn, mutta minulla on video, jotta voit nähdä demon:
Aika siisti, eikö? Nyt meillä on täysin toimiva lohko, joka ei vain renderöi etupäässä, vaan myös hakee API-tiedot ja renderöi ne suoraan lohkoeditorissa – käynnistyspainikkeella!
Mutta jos haluamme ottaa koko WordPress Block Editorin edun vuoksi meidän pitäisi harkita joidenkin lohkon käyttöliittymäelementtien yhdistämistä lohkon säätimet esimerkiksi värien, typografian ja välien asettamiseen. Se on mukava seuraava askel lohkokehityksen oppimismatkalla.