Création d'une interface utilisateur de paramètres pour un bloc WordPress personnalisé PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Création d'une interface utilisateur de paramètres pour un bloc WordPress personnalisé

Jusqu'à présent, nous avons expliqué comment utiliser les données d'une API externe dans un bloc WordPress personnalisé. Nous avons parcouru le processus de récupérer ces données pour les utiliser sur le front-end d'un site WordPress, et comment rendez-le directement dans l'éditeur de blocs WordPress lors du placement du bloc dans le contenu. Cette fois, nous allons relier ces deux articles en nous connectant au panneau de configuration de l'éditeur de blocs pour créer une interface utilisateur de paramètres pour le bloc que nous avons créé.

Travailler avec des API externes dans les blocs WordPress

Vous connaissez le panneau de contrôle auquel je fais référence, n'est-ce pas ? C'est ce panneau sur la droite qui contient les paramètres de publication et de blocage dans l'éditeur de blocs.

Création d'une interface utilisateur de paramètres pour un bloc WordPress personnalisé

Vous voyez cette zone surlignée en rouge ? C'est le panneau de contrôle. Un bloc Paragraphe est actuellement sélectionné et ses paramètres sont affichés dans le panneau. On peut changer les styles, la couleur, la typographie… un certain nombre de choses !

Eh bien, c'est exactement ce que nous faisons cette fois-ci. Nous allons créer les contrôles pour les paramètres du bloc Football Rankings sur lequel nous avons travaillé dans les deux derniers articles. La dernière fois, nous avons créé un bouton dans notre bloc qui récupère les données externes pour le classement du football. Nous connaissions déjà l'URL et les points de terminaison dont nous avions besoin. Mais que se passe-t-il si nous voulons récupérer le classement d'un autre pays ? Ou peut-être une autre ligue ? Que diriez-vous des données d'une autre saison ?

Nous avons besoin de contrôles de formulaire pour ce faire. Nous pourrions utiliser des composants React interactifs - comme Réagir-Sélectionner - pour parcourir les différentes options d'API disponibles pour analyser ces données. Mais ce n'est pas nécessaire puisque WordPress est livré avec un tas de composants de base auxquels nous nous accrochons directement !

La Documentation pour ces composants — appelés InspectorControls — s'améliore dans le Manuel de l'éditeur de blocs WordPress. Cela s'améliorera avec le temps, mais en attendant, nous avons aussi le Livre d'histoire WordPress Gutenberg ainsi que Composants WordPress Gutenberg sites d'aide supplémentaire.

L'architecture des API

Avant de nous accrocher à quoi que ce soit, c'est une bonne idée de définir ce dont nous avons besoin en premier lieu. J'ai cartographié la structure des données RapidAPI que nous récupérons afin que nous sachions ce qui nous est disponible :

Organigramme reliant les points de terminaison de l'API pour les données de bloc WordPress personnalisées qui sont récupérées.
Crédit: API-Football

Les saisons et les pays sont deux points de terminaison de niveau supérieur qui correspondent à un point de terminaison de ligues. À partir de là, nous avons le reste des données que nous utilisons déjà pour remplir le tableau de classement. Donc, ce que nous voulons faire, c'est créer des paramètres dans l'éditeur de blocs WordPress qui filtrent les données par saison, pays et ligue, puis transmettent ces données filtrées dans le tableau de classement. Cela nous donne la possibilité de supprimer le bloc dans n'importe quelle page WordPress ou de publier et d'afficher des variations des données dans le bloc.

Afin d'obtenir le classement, nous devons d'abord obtenir les ligues. Et pour obtenir les ligues, nous devons d'abord obtenir les pays et/ou les saisons. Vous pouvez afficher les différents points de terminaison dans le tableau de bord RapidAPI.

Plein écran pour le tableau de bord Rapid API qui visualise les données de l'API.
Création d'une interface utilisateur de paramètres pour un bloc WordPress personnalisé

Il existe différentes combinaisons de données que nous pouvons utiliser pour remplir les classements, et vous pouvez avoir une préférence pour les données que vous souhaitez. Pour les besoins de cet article, nous allons créer les options suivantes dans le panneau des paramètres de bloc :

  • Choisissez un pays
  • Choisissez la ligue
  • Choisissez la saison

Ensuite, nous aurons un bouton pour soumettre ces sélections et récupérer les données pertinentes et les transmettre au tableau de classement.

Charger et stocker une liste de pays

Nous ne pouvons pas sélectionner le pays pour lequel nous voulons des données si nous n'avons pas de liste de pays parmi lesquels choisir. Donc, notre première tâche est de récupérer une liste de pays à partir de RapidAPI.

L'idéal est de récupérer la liste des pays lorsque le bloc est réellement utilisé dans la page ou le contenu de la publication. Il n'est pas nécessaire de récupérer quoi que ce soit si le bloc n'est pas utilisé. L'approche est très similaire à ce que nous avons fait dans le premier article, la différence étant que nous utilisons un autre point de terminaison d'API et différents attributs pour stocker la liste des pays renvoyés. Il existe d'autres façons WordPress de récupérer des données, comme API-fetch, mais cela sort du cadre de ce que nous faisons ici.

Nous pouvons soit inclure la liste des pays manuellement après l'avoir copiée à partir des données de l'API, soit utiliser une API ou une bibliothèque distincte pour remplir les pays. Mais l'API que nous utilisons a déjà une liste de pays, donc j'utiliserais simplement l'un de ses points de terminaison. Assurons-nous que la liste initiale des pays se charge lorsque le bloc est inséré dans la page ou publiez du contenu dans l'éditeur de blocs :

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

Nous avons une variable d'état pour stocker la liste des pays. Ensuite, nous allons importer un composant du @wordpress/éditeur de blocs package appelé InspectorControls c'est là que se trouvent tous les composants dont nous avons besoin pour créer nos contrôles de paramètres.

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

Le paquet est GitHub repo fait un bon travail d'explication InspectorControls. Dans notre exemple, nous pouvons l'utiliser pour contrôler les paramètres de données de l'API comme le pays, la ligue et la saison. Voici un aperçu pour que vous ayez une idée de l'interface utilisateur que nous créons :

L'interface utilisateur des paramètres personnalisés pour le bloc WordPress montrant les trois options de paramètres pour le bloc personnalisé et un bouton bleu pour récupérer les données.
Création d'une interface utilisateur de paramètres pour un bloc WordPress personnalisé

Et une fois ces sélections effectuées dans les paramètres du bloc, nous les utilisons dans le bloc Edit fonction:


  { countriesList && (
    
  )}

Ici, je m'assure que nous utilisons le rendu conditionnel afin que la fonction ne charge que le composant après la liste des pays est chargée. Si vous vous posez la question LeagueSettings composant, c'est un composant personnalisé que j'ai créé dans un composant séparé components sous-dossier dans le bloc afin que nous puissions avoir un fichier plus propre et plus organisé Edit au lieu de centaines de lignes de données pays à traiter dans un seul fichier.

Structure de fichier pour le répertoire de blocs affichant le fichier en cours.
Création d'une interface utilisateur de paramètres pour un bloc WordPress personnalisé

Nous pouvons l'importer dans le edit.js fichier comme celui-ci:

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

Ensuite, nous transmettons les accessoires requis au LeagueSettings composant du parent Edit composant afin que nous puissions accéder aux variables d'état et aux attributs du LeagueSettings composant enfant. Nous pouvons également le faire avec d'autres méthodes comme la API de contexte pour éviter le forage d'hélice, mais ce que nous avons actuellement est parfaitement adapté à ce que nous faisons.

Les autres parties du Edit fonction peut également être convertie en composants. Par exemple, le code du classement de la ligue peut être placé dans un composant séparé - comme peut-être LeagueTable.js — puis importé comme nous avons importé LeagueSettings into the Edit la fonction.

À l'intérieur de l' LeagueSettings.js filet

LeagueSettings est comme un autre Composant de réaction à partir duquel nous pouvons déstructurer les props du composant parent. Je vais utiliser trois variables d'état et une autre leagueID état parce que nous allons extraire l'ID du league objet:

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

La première chose que nous allons faire est d'importer le PanelBody composant du package @wordpress/block-editor :

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

…et l'inclure dans notre return fonction:

Il y a autres balises et attributs de panneau - c'est juste ma préférence personnelle d'utiliser ceux-ci. Aucun des autres n'est requis… mais regarde tous les composants nous avons à disposition pour faire un panneau de paramètres ! J'aime la simplicité du PanelBody pour notre cas d'utilisation. Il se développe et se réduit pour révéler les paramètres de la liste déroulante du bloc et c'est tout.

En parlant de cela, nous avons un choix à faire pour ces sélections. Nous pourrions utiliser le SelectControl composant ou un ComboBoxControl, que la documentation décrit comme "une version améliorée d'un SelectControl, avec en plus la possibilité de rechercher des options à l'aide d'une entrée de recherche. C'est bien pour nous car la liste des pays peut devenir assez longue et les utilisateurs pourront soit faire une requête de recherche, soit sélectionner dans une liste.

Voici un exemple de la façon dont un ComboboxControl pourrait fonctionner pour notre liste de pays :

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

La ComboboxControl est configurable dans le sens où nous pouvons appliquer un dimensionnement différent pour l'étiquette et les valeurs du contrôle :

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

Mais nos données API ne sont pas dans cette syntaxe, nous pouvons donc convertir le countriesList tableau qui provient du composant parent lorsque le bloc est inclus :

let setupCountrySelect;

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

Lorsqu'un pays est sélectionné dans ComboboxControl, la valeur du pays change et nous filtrons les données en conséquence :

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

Notez que j'utilise trois autres variables d'état pour gérer les changements lorsque la sélection du pays change :

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

Qu'en est-il des autres options de paramètres ?

Je vais montrer le code que j'ai utilisé pour les autres paramètres, mais il ne fait que prendre en compte les cas normaux tout en définissant les erreurs pour les cas particuliers. Par exemple, il y aura des erreurs dans certains pays et ligues car :

  • il n'y a pas de classement pour certaines ligues, et
  • certaines ligues ont des classements mais elles ne sont pas dans un seul tableau.

Ceci n'est pas un tutoriel JavaScript ou React, je vais donc vous laisser gérer les cas particuliers de l'API que vous envisagez d'utiliser :

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

Soumission des sélections de paramètres

Dans le dernier article, nous avons créé un bouton dans l'éditeur de blocs qui récupère les nouvelles données de l'API. Il n'y a plus besoin de cela maintenant que nous avons des paramètres. Eh bien, nous en avons besoin - mais pas là où il se trouve actuellement. Au lieu de l'avoir directement dans le bloc rendu dans l'éditeur de blocs, nous allons le déplacer vers notre PanelBody composant pour soumettre les sélections de paramètres.

Donc, de retour dans 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 && (
        
      )
    }
    
  
)}

Voici le résultat !

Nous sommes très bien placés avec notre bloc. Nous pouvons le rendre dans l'éditeur de blocs et le front-end du site. Nous pouvons récupérer des données à partir d'une API externe en fonction d'une sélection de paramètres que nous avons créés pour filtrer les données. C'est vachement fonctionnel !

Mais il y a une autre chose à laquelle nous devons nous attaquer. À l'heure actuelle, lorsque nous enregistrons la page ou la publication contenant le bloc, les paramètres que nous avons sélectionnés pour le bloc sont réinitialisés. En d'autres termes, ces sélections ne sont enregistrées nulle part. Il y a un peu plus de travail pour rendre ces sélections persistantes. C'est là que nous prévoyons d'aller dans le prochain article, alors restez à l'écoute.

Horodatage:

Plus de Astuces CSS