Een instellingen-UI maken voor een aangepast WordPress-blok PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Een gebruikersinterface voor instellingen maken voor een aangepast WordPress-blok

Tot nu toe hebben we besproken hoe u kunt werken met gegevens van een externe API in een aangepast WordPress-blok. We liepen door het proces van het ophalen van die gegevens voor gebruik aan de voorkant van een WordPress-site, en hoe geef het direct weer in de WordPress Block Editor bij het plaatsen van het blok in de inhoud. Deze keer gaan we die twee artikelen overbruggen door in te haken op het configuratiescherm van de blokeditor om een ​​instellingen-UI te maken voor het blok dat we hebben gemaakt.

Werken met externe API's in WordPress-blokken

U kent het bedieningspaneel waar ik naar verwijs, toch? Het is dat paneel aan de rechterkant dat post- en blokinstellingen bevat in de blokeditor.

Een gebruikersinterface voor instellingen maken voor een aangepast WordPress-blok

Zie je dat rood gemarkeerde gebied? Dat is het bedieningspaneel. Er is momenteel een alineablok geselecteerd en de instellingen ervoor worden weergegeven in het paneel. We kunnen stijlen, kleuren, typografie… een aantal dingen veranderen!

Nou, dat is precies wat we deze keer doen. We gaan de bedieningselementen maken voor de instellingen van het blok Football Rankings waaraan we in de laatste twee artikelen hebben gewerkt. De vorige keer hebben we een knop in ons blok gemaakt die de externe gegevens voor de voetbalranglijst ophaalt. We wisten al welke URL en eindpunten we nodig hadden. Maar wat als we de ranglijst voor een ander land willen ophalen? Of misschien een andere league? Hoe zit het met gegevens van een ander seizoen?

We hebben formuliercontroles nodig om dat te doen. We zouden gebruik kunnen maken van interactieve React-componenten - zoals Reageer-Selecteer - om door de verschillende API-opties te bladeren die beschikbaar zijn om die gegevens te ontleden. Maar dat is niet nodig, aangezien WordPress wordt geleverd met een aantal kerncomponenten waar we direct op inhaken!

De documentatie voor deze componenten — genaamd InspectorControls - gaat steeds beter in de WordPress Block Editor-handboek. Dat zal in de loop van de tijd nog beter worden, maar ondertussen hebben we ook de WordPress Gutenberg-verhalenboek en WordPress Gutenberg-componenten sites voor extra hulp.

De API-architectuur

Voordat we ergens op inhaken, is het een goed idee om in kaart te brengen wat we in de eerste plaats nodig hebben. Ik heb de structuur in kaart gebracht van de RapidAPI-gegevens die we ophalen, zodat we weten wat er voor ons beschikbaar is:

Stroomdiagram dat de API-eindpunten verbindt voor de aangepaste WordPress-blokgegevens die worden opgehaald.
credit: API-Voetbal

Seizoenen en landen zijn twee eindpunten op het hoogste niveau die worden toegewezen aan het eindpunt van een competitie. Van daaruit hebben we de rest van de gegevens die we al gebruiken om de ranglijst te vullen. Dus wat we willen doen, is instellingen maken in de WordPress Block Editor die de gegevens filteren op seizoen, land en competitie, en die gefilterde gegevens vervolgens doorgeven aan de ranglijst. Dat geeft ons de mogelijkheid om het blok op elke WordPress-pagina of -post neer te zetten en variaties van de gegevens in het blok weer te geven.

Om het klassement te krijgen, moeten we eerst de competities krijgen. En om de competities te krijgen, moeten we eerst de landen en/of de seizoenen hebben. In het RapidAPI-dashboard kunt u de verschillende endpoints bekijken.

Volledig scherm voor het Rapid API-dashboard dat de API-gegevens visualiseert.
Een gebruikersinterface voor instellingen maken voor een aangepast WordPress-blok

Er zijn verschillende combinaties van gegevens die we kunnen gebruiken om de ranglijsten in te vullen, en misschien heb je een voorkeur voor welke gegevens je wilt. Omwille van dit artikel gaan we de volgende opties maken in het blokinstellingenpaneel:

  • Kies land
  • Kies Liga
  • Kies Seizoen

Dan hebben we een knop om die selecties in te dienen en de relevante gegevens op te halen en door te geven aan de ranglijst.

Laad en bewaar een lijst met landen

We kunnen niet selecteren voor welk land we gegevens willen als we geen lijst met landen hebben waaruit we kunnen kiezen. Onze eerste taak is dus om een ​​lijst met landen uit RapidAPI te halen.

Het ideale is om de lijst met landen op te halen wanneer het blok daadwerkelijk wordt gebruikt in de pagina- of berichtinhoud. Het is niet nodig om iets op te halen als het blok niet in gebruik is. De aanpak lijkt erg op wat we in deden het eerste artikel, het verschil is dat we een ander API-eindpunt en andere attributen gebruiken om de lijst met geretourneerde landen op te slaan. Er zijn andere WordPress-manieren om gegevens op te halen, zoals api-ophalen, maar dat valt buiten het bestek van wat we hier doen.

We kunnen de landenlijst handmatig opnemen nadat we deze uit de API-gegevens hebben gekopieerd, of we kunnen een afzonderlijke API of bibliotheek gebruiken om de landen in te vullen. Maar de API die we gebruiken heeft al een lijst met landen, dus ik zou gewoon een van de eindpunten gebruiken. Laten we ervoor zorgen dat de initiële landenlijst wordt geladen wanneer het blok in de pagina wordt ingevoegd of inhoud posten in de blokeditor:

// 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));
}, []);

We hebben een statusvariabele om de lijst met landen op te slaan. Vervolgens gaan we een component importeren uit het @wordpress/blok-editor pakket genaamd InspectorControls dat is waar alle componenten die we nodig hebben om onze instellingen te maken, zich bevinden.

import { InspectorControls } from "@wordpress/block-editor";

Het pakket GitHub repo legt goed uit InspectorControls. In ons voorbeeld kunnen we het gebruiken om de API-gegevensinstellingen zoals Land, Competitie en Seizoen te beheren. Hier is een voorbeeld zodat u een idee krijgt van de gebruikersinterface die we maken:

De gebruikersinterface voor aangepaste instellingen voor het WordPress-blok met de drie instellingsopties voor het aangepaste blok en een blauwe knop om de gegevens op te halen.
Een gebruikersinterface voor instellingen maken voor een aangepast WordPress-blok

En zodra die selecties zijn gemaakt in de blokinstellingen, gebruiken we ze in het blok Edit functie:


  { countriesList && (
    
  )}

Hier zorg ik ervoor dat we voorwaardelijke weergave gebruiken, zodat de functie alleen de component laadt na de lijst met landen wordt geladen. Als je je dat afvraagt LeagueSettings component, het is een aangepaste component die ik heb gemaakt in een apart components submap in het blok zodat we een schonere en meer georganiseerde Edit functie in plaats van honderden regels landgegevens die in één bestand moeten worden verwerkt.

Bestandsstructuur voor de blokdirectory die het huidige bestand toont.
Een gebruikersinterface voor instellingen maken voor een aangepast WordPress-blok

We kunnen het importeren in de edit.js bestand als volgt:

import { LeagueSettings } from "./components/LeagueSettings";

Vervolgens geven we de vereiste rekwisieten door aan de LeagueSettings onderdeel van de ouder Edit component zodat we toegang hebben tot de statusvariabelen en attributen van de LeagueSettings onderliggende component. We kunnen dat ook doen met andere methoden zoals de Context-API om propboren te voorkomen, maar wat we nu hebben is perfect geschikt voor wat we doen.

De andere delen van de Edit functie kan ook worden omgezet in componenten. De code voor het klassement van de competitie kan bijvoorbeeld in een apart onderdeel worden geplaatst, zoals misschien LeagueTable.js - en vervolgens geïmporteerd, net zoals we hebben geïmporteerd LeagueSettings in de Edit functie.

Binnen LeagueSettings.js filet

LeagueSettings is net als een ander Reageer component waaruit we de rekwisieten van de bovenliggende component kunnen destructureren. Ik ga drie toestandsvariabelen gebruiken en een extra leagueID state omdat we de ID gaan halen uit het league voorwerp:

const [country, setCountry] = useState(null);
const [league, setLeague] = useState(null);
const [season, setSeason] = useState(null);
const [leagueID, setLeagueID] = useState(null);

Het eerste wat we gaan doen is het importeren van de PanelBody component uit het @wordpress/block-editor pakket:

import { PanelBody } from "@wordpress/block-editor";

…en neem het op in onze return functie:

Er zijn andere paneeltags en attributen - het is gewoon mijn persoonlijke voorkeur om deze te gebruiken. Geen van de anderen is vereist ... maar kijk naar alle componenten we hebben beschikbaar om een ​​instellingenpaneel te maken! Ik hou van de eenvoud van de PanelBody voor onze use-case. Het wordt uitgevouwen en samengevouwen om de vervolgkeuzelijstinstellingen voor het blok te onthullen en dat is alles.

Daarover gesproken, we moeten een keuze maken voor die selecties. We zouden de SelectControl bestanddeel of een ComboBoxControl, die in de documenten wordt beschreven als "een verbeterde versie van een SelectControl, met als toevoeging dat je naar opties kunt zoeken met behulp van een zoekinvoer.” Dat is prettig voor ons, want de lijst met landen kan behoorlijk lang worden en gebruikers kunnen een zoekopdracht uitvoeren of een keuze maken uit een lijst.

Hier is een voorbeeld van hoe a ComboboxControl zou kunnen werken voor onze landenlijst:

 handleCountryChange(value) }
  onInputChange={ (inputValue) => {
    setFilteredCountryOptions(
      setupCountrySelect.filter((option) =>
        option.label
          .toLowerCase()
          .startsWith(inputValue.toLowerCase())
      )
    );
  }}
/>

De ComboboxControl is configureerbaar in die zin dat we verschillende afmetingen kunnen toepassen voor het label en de waarden van het besturingselement:

{
  value: 'small',
  label: 'Small',
},

Maar onze API-gegevens staan ​​niet in deze syntaxis, dus we kunnen de countriesList array die afkomstig is van de bovenliggende component wanneer het blok is opgenomen:

let setupCountrySelect;

setupCountrySelect = countriesList.map((country) => {
  return {
    label: country.name,
    value: country.name,
  };
});

Wanneer een land is geselecteerd uit de ComboboxControl, verandert de landwaarde en filteren we de gegevens dienovereenkomstig:

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

Merk op dat ik nog drie andere staatsvariabelen gebruik om wijzigingen af ​​te handelen wanneer de landselectie verandert:

const [filteredCountryOptions, setFilteredCountryOptions] = useState(setupCountrySelect);
const [filteredLeagueOptions, setFilteredLeagueOptions] = useState(null);
const [filteredSeasonOptions, setFilteredSeasonOptions] = useState(null);

Hoe zit het met de andere instellingsopties?

Ik zal de code laten zien die ik voor de andere instellingen heb gebruikt, maar het enige wat het doet is rekening houden met normale gevallen bij het definiëren van fouten voor speciale gevallen. Er zullen bijvoorbeeld fouten zijn in sommige landen en competities omdat:

  • er zijn geen klassementen voor sommige competities, en
  • sommige competities hebben klassementen, maar ze staan ​​niet in een enkele tabel.

Dit is geen JavaScript- of React-zelfstudie, dus ik zal u de speciale gevallen laten afhandelen voor de API die u van plan bent te gebruiken:

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

De instellingsselecties indienen

In het laatste artikel, hebben we een knop gemaakt in de blokeditor die nieuwe gegevens ophaalt uit de API. Het is niet meer nodig nu we instellingen hebben. Nou, we hebben het wel nodig - alleen niet waar het nu is. In plaats van het rechtstreeks in het blok te hebben dat wordt weergegeven in de blokeditor, gaan we het verplaatsen naar ons PanelBody component om de instellingenselecties in te dienen.

Dus terug naar binnen 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 && (
        
      )
    }
    
  
)}

Hier is het resultaat!

We zitten op een goede plek met ons blok. We kunnen het weergeven in de blokeditor en de voorkant van de site. We kunnen gegevens ophalen van een externe API op basis van een selectie van instellingen die we hebben gemaakt om de gegevens te filteren. Het is behoorlijk functioneel!

Maar er is nog iets dat we moeten aanpakken. Wanneer we nu de pagina of het bericht met het blok opslaan, worden de instellingen die we voor het blok hebben geselecteerd, gereset. Met andere woorden, die selecties worden nergens opgeslagen. Er is wat meer werk om die selecties blijvend te maken. Dat is waar we naartoe gaan in het volgende artikel, dus houd ons in de gaten.

Tijdstempel:

Meer van CSS-trucs