Oprettelse af en indstillingsbrugergrænseflade til en brugerdefineret WordPress Block PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Oprettelse af en indstillingsbrugergrænseflade til en brugerdefineret WordPress-blok

Indtil videre har vi dækket, hvordan man arbejder med data fra en ekstern API i en tilpasset WordPress-blok. Vi gik gennem processen med hente disse data til brug på frontend af et WordPress-websted, og hvordan man gengiv det direkte i WordPress Block Editor når du placerer blokken i indhold. Denne gang skal vi slå bro mellem disse to artikler ved at tilslutte os blokeditorens kontrolpanel for at oprette en brugergrænseflade til indstillinger for den blok, vi lavede.

Arbejde med eksterne API'er i WordPress-blokke

Du kender kontrolpanelet, jeg henviser til, ikke? Det er det panel til højre, der indeholder post- og blokindstillinger i blokeditoren.

Oprettelse af en indstillingsbrugergrænseflade til en brugerdefineret WordPress-blok

Kan du se det røde fremhævede område? Det er kontrolpanelet. En afsnitsblok er i øjeblikket valgt, og indstillingerne for den vises i panelet. Vi kan ændre stilarter, farve, typografi ... en række ting!

Nå, det er præcis, hvad vi gør denne gang. Vi skal lave kontrolelementerne for indstillingerne af den fodboldrangeringsblokke, som vi arbejdede på i de sidste to artikler. Sidste gang lavede vi en knap i vores blok, der henter de eksterne data til fodboldranglisten. Vi kendte allerede den URL og de endepunkter, vi havde brug for. Men hvad nu hvis vi ønsker at hente rangering for et andet land? Eller måske en anden liga? Hvad med data fra en anden sæson?

Vi har brug for formularkontrol til at gøre det. Vi kunne gøre brug af interaktive React-komponenter - f.eks Reager-Vælg — for at gennemse de forskellige API-indstillinger, der er tilgængelige for at parse disse data. Men det er der ikke behov for, da WordPress leveres med en masse kernekomponenter, som vi kobler direkte ind i!

dokumentation for disse komponenter - kaldet InspectorControls — bliver bedre i WordPress Block Editor Håndbog. Det bliver endnu bedre med tiden, men i mellemtiden har vi også WordPress Gutenberg historiebog , WordPress Gutenberg-komponenter websteder for yderligere hjælp.

API-arkitekturen

Inden vi kobler os på noget, er det en god idé at kortlægge, hvad det er, vi har brug for i første omgang. Jeg har kortlagt strukturen af ​​de RapidAPI-data, vi henter, så vi ved, hvad der er tilgængeligt for os:

Flowdiagram, der forbinder API-endepunkterne for de tilpassede WordPress-blokdata, der hentes.
Credit: API-Fodbold

Sæsoner og lande er to endepunkter på øverste niveau, der knytter sig til et ligaslutpunkt. Derfra har vi resten af ​​de data, vi allerede bruger til at udfylde rangeringstabellen. Så det, vi vil gøre, er at oprette indstillinger i WordPress Block Editor, der filtrerer dataene efter sæson, land og liga, og derefter overfører de filtrerede data til ranglisten. Det giver os mulighed for at droppe blokeringen på en hvilken som helst WordPress-side eller post og vise variationer af dataene i blokken.

For at få stillingen skal vi først få ligaerne. Og for at få ligaerne skal vi først have landene og/eller sæsonerne. Du kan se de forskellige endepunkter i RapidAPI-dashboardet.

Fuld skærm til Rapid API-dashboardet, der visualiserer API-dataene.
Oprettelse af en indstillingsbrugergrænseflade til en brugerdefineret WordPress-blok

Der er forskellige kombinationer af data, som vi kan bruge til at udfylde ranglisten, og du har måske en præference for, hvilke data du ønsker. Af hensyn til denne artikel vil vi oprette følgende muligheder i panelet med blokindstillinger:

  • Vælg land
  • Vælg Liga
  • Vælg Sæson

Så har vi en knap til at indsende disse valg og hente de relevante data og sende dem til rangeringstabellen.

Indlæs og gem en liste over lande

Vi kan ikke vælge, hvilket land vi vil have data for, hvis vi ikke har en liste over lande at vælge imellem. Så vores første opgave er at få fat i en liste over lande fra RapidAPI.

Det ideelle er at hente listen over lande, når blokken rent faktisk bruges i siden eller indlæggets indhold. Der er ingen grund til at hente noget, hvis blokken ikke er i brug. Fremgangsmåden ligner meget, hvad vi gjorde i den første artikel, forskellen er, at vi bruger et andet API-slutpunkt og forskellige attributter til at gemme listen over returnerede lande. Der er andre WordPress måder at hente data på, f.eks api-hent, men det er uden for rammerne af, hvad vi laver her.

Vi kan enten inkludere landelisten manuelt efter at have kopieret den fra API-dataene, eller vi kan bruge en separat API eller et separat bibliotek til at udfylde landene. Men den API, vi bruger, har allerede en liste over lande, så jeg ville bare bruge et af dets endepunkter. Lad os sørge for, at den første landeliste indlæses, når blokken indsættes på siden eller postindhold i blokeditoren:

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

Vi har en tilstandsvariabel til at gemme listen over lande. Dernæst skal vi importere en komponent fra @wordpress/blok-editor pakke kaldet InspectorControls det er der, hvor alle de komponenter, vi skal bruge for at oprette vores indstillingskontroller, er placeret.

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

Pakkens GitHub repo gør et godt stykke arbejde med at forklare InspectorControls. I vores eksempel kan vi bruge det til at styre API-dataindstillingerne som Land, Liga og Sæson. Her er en forhåndsvisning, så du får en idé om den brugergrænseflade, vi laver:

Brugergrænsefladen for brugerdefinerede indstillinger for WordPress-blokken, der viser de tre indstillingsmuligheder for den tilpassede blok og en blå knap til at hente dataene.
Oprettelse af en indstillingsbrugergrænseflade til en brugerdefineret WordPress-blok

Og når disse valg er foretaget i blokindstillingerne, bruger vi dem i blokkens Edit funktion:


  { countriesList && (
    
  )}

Her sørger jeg for, at vi bruger betinget gengivelse, så funktionen kun indlæser komponenten efter listen over lande er indlæst. Hvis du undrer dig over det LeagueSettings komponent, det er en brugerdefineret komponent, jeg har oprettet i en separat components undermappe i blokken, så vi kan få en renere og mere organiseret Edit funktion i stedet for hundredvis af linjer med landedata, der skal håndteres i en enkelt fil.

Filstruktur for blokbiblioteket, der viser den aktuelle fil.
Oprettelse af en indstillingsbrugergrænseflade til en brugerdefineret WordPress-blok

Vi kan importere det til edit.js fil som denne:

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

Dernæst videregiver vi de nødvendige rekvisitter til LeagueSettings komponent fra forælderen Edit komponent, så vi kan få adgang til tilstandsvariabler og attributter fra LeagueSettings barn komponent. Det kan vi også gøre med andre metoder som f.eks Context API for at undgå propboring, men det, vi har lige nu, passer perfekt til det, vi laver.

De andre dele af Edit funktion kan også konverteres til komponenter. For eksempel kan ligaens stillingskode sættes i en separat komponent - som måske LeagueTable.js — og derefter importeret ligesom vi importerede LeagueSettings ind i Edit funktion.

Inde LeagueSettings.js fil

LeagueSettings er ligesom en anden Reaktionskomponent hvorfra vi kan destrukturere rekvisitterne fra den overordnede komponent. Jeg vil bruge tre tilstandsvariable og en yderligere leagueID stat, fordi vi skal udtrække ID'et fra league objekt:

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

Den første ting vi skal gøre er at importere PanelBody komponent fra @wordpress/block-editor-pakken:

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

...og inkludere det i vores return fungere:

Der er andre panel tags og attributter — Det er bare min personlige præference at bruge disse. Ingen af ​​de andre er påkrævet... men se på alle komponenterne vi har mulighed for at lave et indstillingspanel! Jeg kan godt lide enkelheden i PanelBody til vores brugssag. Det udvider og kollapser for at afsløre dropdown-indstillingerne for blokken, og det er det.

Apropos det, vi har et valg at træffe for disse valg. Vi kunne bruge SelectControl komponent eller en ComboBoxControl, som dokumenterne beskriver som "en forbedret version af en SelectControl, med tilføjelsen af ​​at være i stand til at søge efter muligheder ved hjælp af et søgeinput." Det er rart for os, fordi listen over lande kan blive temmelig lang, og brugerne vil enten kunne lave en søgeforespørgsel eller vælge fra en liste.

Her er et eksempel på, hvordan en ComboboxControl kunne fungere for vores landeliste:

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

ComboboxControl er konfigurerbar i den forstand, at vi kan anvende forskellige størrelser for kontrollens etiket og værdier:

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

Men vores API-data er ikke i denne syntaks, så vi kan konvertere countriesList array, der kommer fra den overordnede komponent, når blokken er inkluderet:

let setupCountrySelect;

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

Når et land er valgt fra ComboboxControl, ændres landeværdien, og vi filtrerer dataene i overensstemmelse hermed:

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

Bemærk, at jeg bruger yderligere tre tilstandsvariabler til at håndtere ændringer, når landevalget ændres:

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

Hvad med de andre indstillingsmuligheder?

Jeg vil vise koden, som jeg brugte til de andre indstillinger, men alt det gør er at tage normale tilfælde i betragtning, mens jeg definerer fejl for specielle tilfælde. For eksempel vil der være fejl i nogle lande og ligaer, fordi:

  • der er ingen stillinger for nogle ligaer, og
  • nogle ligaer har stilling, men de er ikke i en enkelt tabel.

Dette er ikke en JavaScript- eller React-tutorial, så jeg vil lade dig håndtere de særlige tilfælde for den API, du planlægger at bruge:

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

Indsendelse af indstillingsvalg

I sidste artikel, lavede vi en knap i blokeditoren, der henter friske data fra API'et. Der er ikke mere behov for det nu, hvor vi har indstillinger. Nå, vi har brug for det - bare ikke hvor det er i øjeblikket. I stedet for at have det direkte i blokken, der er gengivet i blokeditoren, flytter vi det til vores PanelBody komponent for at indsende indstillingsvalgene.

Så ind igen 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 && (
        
      )
    }
    
  
)}

Her er resultatet!

Vi er et rigtig godt sted med vores blok. Vi kan gengive det i blok-editoren og frontenden af ​​webstedet. Vi kan hente data fra en ekstern API baseret på et udvalg af indstillinger, vi har lavet, som filtrerer dataene. Det er ret funktionelt!

Men der er en anden ting, vi skal tackle. Lige nu, når vi gemmer siden eller indlægget, der indeholder blokken, nulstilles de indstillinger, vi valgte for blokeringen. Med andre ord gemmes disse valg ikke nogen steder. Der er lidt mere arbejde for at gøre disse valg vedvarende. Det er der, vi planlægger at tage hen i den næste artikel, så følg med.

Tidsstempel:

Mere fra CSS-tricks