Ez az utolsó cikkem folytatása erről „Külső API-adatok megjelenítése WordPress-blokkokban a kezelőfelületen”. Az utolsóban megtanultuk, hogyan kell egy külső API-t használni, és integrálni egy blokkkal, amely a lekért adatokat egy WordPress-webhely előlapján jeleníti meg.
A helyzet az, hogy ezt úgy értük el, hogy megakadályozzuk, hogy lássuk az adatokat a WordPress blokkszerkesztőben. Más szóval, beilleszthetjük a blokkot egy oldalra, de nem kapunk előnézetet. Csak akkor láthatjuk a blokkot, amikor közzétesszük.
Tekintsük újra az előző cikkben készített példablokk-bővítményt. Csak ezúttal a WordPress JavaScript és React ökoszisztémáját fogjuk használni, hogy lekérjük és megjelenítsük ezeket az adatokat a háttérblokkszerkesztőben is.
Ahol abbahagytuk
Miközben ezt elindítjuk, itt egy demó ahol az utolsó cikkben landoltunk, amelyre hivatkozhat. Talán észrevetted, hogy használtam a render_callback
módszert az utolsó cikkben, hogy felhasználhassam a PHP-fájl attribútumait, és megjeleníthessem a tartalmat.
Nos, ez hasznos lehet olyan helyzetekben, amikor esetleg valamilyen natív WordPress vagy PHP függvényt kell használnia dinamikus blokkok létrehozásához. Ha azonban csak a WordPress JavaScript és React (konkrétan JSX) ökoszisztémáját szeretné használni a statikus HTML megjelenítéséhez az adatbázisban tárolt attribútumokkal együtt, akkor csak a Edit
és a Save
a blokk bővítmény funkciói.
- A
Edit
függvény a tartalmat az alapján jeleníti meg, amit a Blokkszerkesztőben szeretne látni. Itt interaktív React összetevőket találhat. - A
Save
függvény a tartalmat az alapján jeleníti meg, amit a kezelőfelületen szeretne látni. Itt nem lehetnek a szokásos React komponensek vagy horgok. Ez az adatbázisba mentett statikus HTML visszaadására szolgál az attribútumokkal együtt.
A Save
funkció az, ahol ma lógunk. Létrehozhatunk interaktív komponenseket a kezelőfelületen, de ehhez manuálisan kell hozzáadnunk és hozzá kell férnünk a felületen kívül Save
funkciót egy fájlban, mint az előző cikkben.
Tehát ugyanazt a területet fogom kifejteni, mint az előző cikkben, de ezúttal az előnézetet láthatja a Blokkszerkesztőben előtt közzéteszed a kezelőfelületen.
A blokk kellékek
Szándékosan kihagytam minden magyarázatot a edit
függvény kellékei az utolsó cikkben, mert az elvonta volna a hangsúlyt a fő pontról, a megjelenítésről.
Ha React háttérrel érkezik, valószínűleg érteni fogja, miről beszélek, de ha még nem ismeri ezt, azt javaslom az alkatrészek és kellékek ellenőrzése a React dokumentációjában.
Ha naplózzuk a props
objektumot a konzolra, akkor a blokkunkhoz kapcsolódó WordPress függvények és változók listáját adja vissza:
Nekünk csak a attributes
tárgy és a setAttributes
függvény, amelyet tönkre fogok tenni a props
objektum a kódomban. Az utolsó cikkben módosítottam a RapidAPI kódját, hogy tárolhassam az API-adatokat setAttributes()
. A kellékek csak olvashatók, így közvetlenül nem tudjuk módosítani őket.
A blokktámaszok hasonlóak az állapotváltozókhoz és setState
a Reactban, de a React a kliens oldalon működik és setAttributes()
A bejegyzés mentése után az attribútumok végleges tárolására szolgál a WordPress adatbázisban. Tehát azt kell tennünk, hogy megmentjük őket attributes.data
majd ezt hívja meg a kezdeti értéknek useState()
változót.
edit
funkció
A Bemásolom és beillesztem azt a HTML kódot, amit használtunk football-rankings.php
az utolsó cikkben, és módosítsa egy kicsit, hogy a JavaScript-háttérre váltson. Emlékszel, hogyan hoztunk létre két további fájlt az előző cikkben a kezelőfelület stílusához és szkriptekhez? Ahogyan ma hozzáállunk a dolgokhoz, nincs szükség ilyen fájlok létrehozására. Ehelyett az egészet áthelyezhetjük a Edit
funkciót.
Teljes kód
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}
);
})}
);
}
)}
)}
);
}
Mellékeltem a React horgot useState()
ból ből @wordpress/element
ahelyett, hogy a React könyvtárból használná. Ez azért van, mert ha a szokásos módon tölteném be, akkor minden általam használt blokkhoz letöltené a Reactot. De ha használom @wordpress/element
egyetlen forrásból töltődik be, azaz a React tetején lévő WordPress rétegből.
Ezúttal szintén nem csomagoltam be a kódot useEffect()
hanem egy olyan függvényen belül, amely csak akkor hívódik meg, ha egy gombra kattintunk, így élő előnézetben láthatjuk a beolvasott adatokat. nevű állapotváltozót használtam apiData
hogy a bajnoki tabellát feltételessé tegye. Tehát, miután a gombra kattintott és az adatok lekérésre kerültek, beállítom apiData
a benne lévő új adatokhoz fetchData()
és rendelkezésre áll egy újrarenderelés a labdarúgó-ranglista HTML-kódjával.
Észre fogja venni, hogy a bejegyzés mentése és az oldal frissítése után a bajnoki táblázat eltűnik. Ez azért van így, mert üres állapotot használunk (null
) számára apiData
kezdeti értéke. A bejegyzés mentésekor az attribútumok mentésre kerülnek a attributes.data
objektum, és ezt a kezdeti értéknek nevezzük useState()
ilyen változó:
const [apiData, setApiData] = useState(attributes.data);
save
funkció
A Majdnem pontosan ugyanazt fogjuk csinálni a save
funkciót, de módosítsa egy kicsit. Például nincs szükség az „Adatok lekérése” gombra az előlapon, és a apiData
állapotváltozó sem szükséges, mert már ellenőrizzük a edit
funkció. De szükségünk van egy véletlenre apiData
változó, amely ellenőrzi attributes.data
feltételesen rendereli a JSX-et, különben meghatározatlan hibákat fog dobni, és a Blokkszerkesztő felhasználói felülete üres lesz.
Teljes kód
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}
);
})}
);
})}
)}
);
}
Ha módosítja a save
függvény, miután egy blokk már jelen van a Blokkszerkesztőben, a következőhöz hasonló hibát jelez:
Ennek az az oka, hogy a mentett tartalom jelölése eltér az új tartalom jelölésétől save
funkció. Mivel fejlesztési módban vagyunk, egyszerűbb eltávolítani a blokkot az aktuális oldalról, és új blokkként újra beilleszteni – így a frissített kód kerül felhasználásra, és a dolgok ismét szinkronban vannak.
Ez a helyzet, amikor eltávolítjuk és újra hozzáadjuk, elkerülhető, ha használtuk volna a render_callback
módszert, mivel a kimenet dinamikus, és a mentési funkció helyett a PHP vezérli. Tehát minden módszernek megvannak a maga előnyei és hátrányai.
Tom Nowell alapos magyarázatot ad arra vonatkozóan, hogy mit ne tegyünk a save
funkciója ez a Stack Overflow válasz.
A blokk stílusa a szerkesztőben és a kezelőfelületen
Ami a stílust illeti, szinte ugyanaz lesz, mint amit az előző cikkben megnéztünk, de néhány apró változtatással, amelyeket a megjegyzésekben kifejtettem. Itt csak a teljes stílusokat közlöm, mivel ez csak a koncepció bizonyítéka, nem pedig valami másolás-beillesztés (kivéve, ha valóban szüksége van egy blokkra a futball-ranglista ilyen stílusú megjelenítéséhez). És ne feledje, hogy továbbra is SCSS-t használok, amely CSS-re fordítja a buildet.
Szerkesztői stílusok
/* 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 stílusok
/* 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;
}
}
}
Ezt adjuk hozzá src/style.scss
amely mind a szerkesztőben, mind a frontendben gondoskodik a stílusról. Nem fogom tudni megosztani a demó URL-jét, mivel szerkesztői hozzáférést igényel, de van egy videóm, hogy lássa a demót:
Elég ügyes, igaz? Most már van egy teljesen működő blokk, amely nem csak az előlapon jelenít meg, hanem lekéri az API-adatokat is, és ott rendereli a Blokkszerkesztőben – a rendszerindításhoz egy frissítés gombbal!
De ha venni akarjuk Tele A WordPress Block Editor előnye, hogy fontolóra kell vennünk a blokk felhasználói felület egyes elemeinek leképezését blokkvezérlők olyan dolgokhoz, mint a szín, a tipográfia és a térköz beállítása. Ez egy szép következő lépés a blokkfejlesztési tanulási útban.