Finora abbiamo spiegato come lavorare con i dati di un'API esterna in un blocco WordPress personalizzato. Abbiamo seguito il processo di recuperando quei dati per l'uso sul front-end di un sito WordPress e come esegui il rendering direttamente nell'editor a blocchi di WordPress quando si inserisce il blocco nel contenuto. Questa volta, collegheremo questi due articoli collegandoci al pannello di controllo dell'editor dei blocchi per creare un'interfaccia utente delle impostazioni per il blocco che abbiamo creato.
Lavorare con API esterne nei blocchi di WordPress
Hai presente il pannello di controllo a cui mi riferisco, vero? È quel pannello sulla destra che contiene le impostazioni dei post e dei blocchi nell'editor dei blocchi.
Vedi quell'area evidenziata in rosso? Quello è il pannello di controllo. Un blocco Paragrafo è attualmente selezionato e le relative impostazioni vengono visualizzate nel pannello. Possiamo cambiare stile, colore, tipografia... un sacco di cose!
Bene, questo è esattamente quello che stiamo facendo questa volta. Creeremo i controlli per le impostazioni del blocco Football Rankings su cui abbiamo lavorato negli ultimi due articoli. L'ultima volta, abbiamo creato un pulsante nel nostro blocco che recupera i dati esterni per le classifiche di calcio. Conoscevamo già l'URL e gli endpoint di cui avevamo bisogno. Ma cosa succede se vogliamo recuperare la classifica per un paese diverso? O forse un campionato diverso? Che ne dici dei dati di una stagione diversa?
Abbiamo bisogno di controlli del modulo per farlo. Potremmo utilizzare componenti React interattivi, ad esempio Reagisci-Seleziona — per sfogliare le varie opzioni API disponibili per analizzare i dati. Ma non ce n'è bisogno poiché WordPress viene fornito con una serie di componenti principali a cui ci colleghiamo direttamente!
I documentazione per questi componenti — chiamato InspectorControls
- sta migliorando nel Manuale dell'editor di blocchi di WordPress. Andrà ancora meglio nel tempo, ma nel frattempo abbiamo anche il Libro di fiabe di Gutenberg per WordPress ed Componenti Gutenberg di WordPress siti per ulteriore assistenza.
L'architettura dell'API
Prima di agganciarci a qualsiasi cosa, è una buona idea mappare ciò di cui abbiamo bisogno in primo luogo. Ho mappato la struttura dei dati RapidAPI che stiamo recuperando in modo da sapere cosa è a nostra disposizione:
Le stagioni e i paesi sono due endpoint di primo livello associati a un endpoint di campionati. Da lì, abbiamo il resto dei dati che stiamo già utilizzando per popolare la tabella delle classifiche. Quindi, quello che vogliamo fare è creare impostazioni nel Block Editor di WordPress che filtrino i dati per Stagione, Paese e Lega, quindi trasmettano i dati filtrati nella tabella delle classifiche. Questo ci dà la possibilità di rilasciare il blocco in qualsiasi pagina o post di WordPress e visualizzare le variazioni dei dati nel blocco.
Per ottenere la classifica, dobbiamo prima ottenere i campionati. E per ottenere i campionati, dobbiamo prima ottenere i paesi e/o le stagioni. Puoi visualizzare i vari endpoint nella dashboard di RapidAPI.
Esistono diverse combinazioni di dati che possiamo utilizzare per popolare le classifiche e potresti avere una preferenza per i dati che desideri. Per il bene di questo articolo, creeremo le seguenti opzioni nel pannello delle impostazioni del blocco:
- Scegli il Paese
- Scegli Lega
- Scegli Stagione
Quindi avremo un pulsante per inviare quelle selezioni e recuperare i dati rilevanti e passarli nella tabella delle classifiche.
Carica e memorizza un elenco di paesi
Non possiamo selezionare il paese per il quale desideriamo i dati se non disponiamo di un elenco di paesi tra cui scegliere. Quindi, il nostro primo compito è ottenere un elenco di paesi da RapidAPI.
L'ideale è recuperare l'elenco dei paesi quando il blocco viene effettivamente utilizzato nella pagina o nel contenuto del post. Non è necessario recuperare nulla se il blocco non è in uso. L'approccio è molto simile a quello che abbiamo fatto in il primo articolo, con la differenza che stiamo utilizzando un endpoint API diverso e attributi diversi per archiviare l'elenco dei paesi restituiti. Ci sono altri modi WordPress per recuperare i dati, come api-fetch, ma questo esula dall'ambito di ciò che stiamo facendo qui.
Possiamo includere manualmente l'elenco dei paesi dopo averlo copiato dai dati API oppure utilizzare un'API o una libreria separata per popolare i paesi. Ma l'API che stiamo usando ha già un elenco di paesi, quindi userei solo uno dei suoi endpoint. Assicuriamoci che l'elenco dei paesi iniziale venga caricato quando il blocco viene inserito nella pagina o pubblica il contenuto nell'editor del blocco:
// edit.js
const [countriesList, setCountriesList] = useState(null);
useEffect(() => {
let countryOptions = {
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/countries", countryOptions)
.then( (response) => response.json() )
.then( (response) => {
let countriesArray = { ...response };
console.log("Countries list", countriesArray.response);
setCountriesList(countriesArray.response);
})
.catch((err) => console.error(err));
}, []);
Abbiamo una variabile di stato per memorizzare l'elenco dei paesi. Successivamente, importeremo un componente dal file @wordpress/editor-di-blocchi pacchetto chiamato InspectorControls
che è dove si trovano tutti i componenti di cui abbiamo bisogno per creare i nostri controlli delle impostazioni.
import { InspectorControls } from "@wordpress/block-editor";
Il pacco è Repository GitHub fa un buon lavoro spiegando InspectorControls
. Nel nostro esempio, possiamo usarlo per controllare le impostazioni dei dati API come Paese, Lega e Stagione. Ecco un'anteprima in modo da farti un'idea dell'interfaccia utente che stiamo realizzando:
E una volta effettuate queste selezioni nelle impostazioni del blocco, le usiamo del blocco Edit
function:
{ countriesList && (
)}
Qui, mi sto assicurando che stiamo usando il rendering condizionale in modo che la funzione carichi solo il componente dopo l'elenco dei paesi viene caricato. Se te lo stai chiedendo LeagueSettings
componente, è un componente personalizzato che ho creato in un file separato components
sottocartella nel blocco in modo da poter avere un file più pulito e organizzato Edit
funzione invece di centinaia di righe di dati del paese da gestire in un unico file.
Possiamo importarlo nel file edit.js
file come questo:
import { LeagueSettings } from "./components/LeagueSettings";
Successivamente, passiamo gli oggetti di scena richiesti al file LeagueSettings
componente dal genitore Edit
componente in modo da poter accedere alle variabili di stato e agli attributi dal LeagueSettings
componente figlio. Possiamo farlo anche con altri metodi come il API di contesto per evitare la perforazione dell'elica, ma quello che abbiamo in questo momento è perfettamente adatto a quello che stiamo facendo.
Le altre parti del Edit
la funzione può anche essere convertita in componenti. Ad esempio, il codice della classifica del campionato può essere inserito in un componente separato, ad esempio forse LeagueTable.js
- e poi importato proprio come abbiamo importato LeagueSettings
nella Edit
funzione.
LeagueSettings.js
filetto
All'interno del LeagueSettings
è proprio come un altro Reagire componente da cui possiamo destrutturare gli oggetti di scena dal componente genitore. Userò tre variabili di stato e un'altra leagueID
state perché estraiamo l'ID dal file league
oggetto:
const [country, setCountry] = useState(null);
const [league, setLeague] = useState(null);
const [season, setSeason] = useState(null);
const [leagueID, setLeagueID] = useState(null);
La prima cosa che faremo è importare il file PanelBody
componente dal pacchetto @wordpress/block-editor:
import { PanelBody } from "@wordpress/block-editor";
…e includilo nel nostro return
funzione:
Ci sono altri tag e attributi del pannello - è solo una mia preferenza personale usare questi. Nessuno degli altri è richiesto... ma guarda tutti i componenti abbiamo a disposizione per fare un pannello delle impostazioni! Mi piace la semplicità del PanelBody
per il nostro caso d'uso. Si espande e si comprime per rivelare le impostazioni del menu a discesa per il blocco e il gioco è fatto.
A proposito, abbiamo una scelta da fare per quelle selezioni. Potremmo usare il SelectControl
componente o a ComboBoxControl
, che i documenti descrivono come "una versione migliorata di a SelectControl
, con l'aggiunta della possibilità di cercare opzioni utilizzando un input di ricerca. Questo è bello per noi perché l'elenco dei paesi potrebbe diventare piuttosto lungo e gli utenti saranno in grado di eseguire una query di ricerca o selezionare da un elenco.
Ecco un esempio di come a ComboboxControl
potrebbe funzionare per la nostra lista di paesi:
handleCountryChange(value) }
onInputChange={ (inputValue) => {
setFilteredCountryOptions(
setupCountrySelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase())
)
);
}}
/>
I ComboboxControl
è configurabile nel senso che possiamo applicare dimensioni diverse per l'etichetta e i valori del controllo:
{
value: 'small',
label: 'Small',
},
Ma i nostri dati API non sono in questa sintassi, quindi possiamo convertire il file countriesList
array che proviene dal componente genitore quando il blocco è incluso:
let setupCountrySelect;
setupCountrySelect = countriesList.map((country) => {
return {
label: country.name,
value: country.name,
};
});
Quando si seleziona un paese dal file ComboboxControl
, il valore del paese cambia e filtriamo i dati di conseguenza:
function handleCountryChange(value) {
// Set state of the country
setCountry(value);
// League code from RapidAPI
const options = {
method: "GET",
headers: {
"X-RapidAPI-Key": "Your RapidAPI key",
"X-RapidAPI-Host": "api-football-v1.p.rapidapi.com",
},
};
fetch(`https://api-football-v1.p.rapidapi.com/v3/leagues?country=${value}`, options)
.then((response) => response.json())
.then((response) => {
return response.response;
})
.then((leagueOptions) => {
// Set state of the league variable
setLeague(leagueOptions);
// Convert it as we did for Country options
setupLeagueSelect = leagueOptions.map((league) => {
return {
label: league.league.name,
value: league.league.name,
};
});
setFilteredLeagueOptions(setupLeagueSelect);
})
.catch((err) => console.error(err));
}
Nota che sto usando altre tre variabili di stato per gestire le modifiche quando cambia la selezione del paese:
const [filteredCountryOptions, setFilteredCountryOptions] = useState(setupCountrySelect);
const [filteredLeagueOptions, setFilteredLeagueOptions] = useState(null);
const [filteredSeasonOptions, setFilteredSeasonOptions] = useState(null);
E le altre opzioni di impostazione?
Mostrerò il codice che ho usato per le altre impostazioni, ma tutto ciò che fa è tenere conto dei casi normali durante la definizione degli errori per casi speciali. Ad esempio, ci saranno errori in alcuni paesi e campionati perché:
- non ci sono classifiche per alcuni campionati, e
- alcuni campionati hanno classifiche ma non sono in un'unica classifica.
Questo non è un tutorial su JavaScript o React, quindi ti lascerò gestire i casi speciali per l'API che prevedi di utilizzare:
function handleLeagueChange(value) {
setLeague(value);
if (league) {
const selectedLeague = league.filter((el) => {
if (el.league.name === value) {
return el;
}
});
if (selectedLeague) {
setLeague(selectedLeague[0].league.name);
setLeagueID(selectedLeague[0].league.id);
setupSeasonSelect = selectedLeague[0].seasons.map((season) => {
return {
label: season.year,
value: season.year,
};
});
setFilteredSeasonOptions(setupSeasonSelect);
}
} else {
return;
}
}
function handleSeasonChange(value) {
setSeason(value);
}
Invio delle selezioni delle impostazioni
Nel ultimo articolo, abbiamo creato un pulsante nell'editor dei blocchi che recupera dati aggiornati dall'API. Non ce n'è più bisogno ora che abbiamo le impostazioni. Bene, ne abbiamo bisogno, ma non dove si trova attualmente. Invece di averlo direttamente nel blocco di cui è stato eseguito il rendering nell'editor di blocchi, lo sposteremo nel nostro PanelBody
componente per inviare le selezioni delle impostazioni.
Quindi, di nuovo dentro LeagueSettings.js
:
// When countriesList is loaded, show the country combo box
{ countriesList && (
handleCountryChange(value)}
onInputChange={(inputValue) => {
setFilteredCountryOptions(
setupCountrySelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase())
)
);
}}
/>
)}
// When filteredLeagueOptions is set through handleCountryChange, show league combobox
{ filteredLeagueOptions && (
handleLeagueChange(value)}
onInputChange={(inputValue) => {
setFilteredLeagueOptions(
setupLeagueSelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase())
)
);
}}
/>
)}
// When filteredSeasonOptions is set through handleLeagueChange, show season combobox
{ filteredSeasonOptions && (
handleSeasonChange(value)}
onInputChange={
(inputValue) => {
setFilteredSeasonOptions(
setupSeasonSelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase()
)
);
}
}
/>
// When season is set through handleSeasonChange, show the "Fetch data" button
{
season && (
)
}
)}
Ecco il risultato!
Siamo a buon punto con il nostro blocco. Possiamo eseguirne il rendering nell'editor di blocchi e nel front-end del sito. Possiamo recuperare i dati da un'API esterna in base a una selezione di impostazioni che abbiamo creato che filtra i dati. È davvero dannatamente funzionale!
Ma c'è un'altra cosa che dobbiamo affrontare. In questo momento, quando salviamo la pagina o il post che contiene il blocco, le impostazioni che abbiamo selezionato per il blocco vengono ripristinate. In altre parole, quelle selezioni non vengono salvate da nessuna parte. C'è ancora un po' di lavoro per rendere queste selezioni persistenti. È lì che intendiamo andare nel prossimo articolo, quindi rimanete sintonizzati.