Rendu des données API externes dans les blocs WordPress sur le back-end PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Rendu des données d'API externes dans des blocs WordPress sur le back-end

Ceci est la suite de mon dernier article sur "Rendu des données d'API externes dans des blocs WordPress sur le front-end". Dans ce dernier, nous avons appris à prendre une API externe et à l'intégrer à un bloc qui restitue les données récupérées sur le front-end d'un site WordPress.

Le fait est que nous avons accompli cela d'une manière qui nous empêche de voir les données dans l'éditeur de blocs WordPress. En d'autres termes, nous pouvons insérer le bloc sur une page mais nous n'en avons aucun aperçu. Nous ne voyons le bloc que lorsqu'il est publié.

Reprenons l'exemple de plugin de bloc que nous avons créé dans le dernier article. Seulement cette fois, nous allons utiliser l'écosystème JavaScript et React de WordPress pour récupérer et restituer également ces données dans l'éditeur de blocs back-end.

Où nous nous sommes arrêtés

Alors que nous lançons cela, voici une démo où nous avons atterri dans le dernier article que vous pouvez référencer. Vous avez peut-être remarqué que j'ai utilisé un render_callback méthode dans le dernier article afin que je puisse utiliser les attributs du fichier PHP et rendre le contenu.

Eh bien, cela peut être utile dans les situations où vous devrez peut-être utiliser une fonction WordPress ou PHP native pour créer des blocs dynamiques. Mais si vous souhaitez utiliser uniquement l'écosystème JavaScript et React (JSX, en particulier) de WordPress pour rendre le HTML statique avec les attributs stockés dans la base de données, vous n'avez qu'à vous concentrer sur le Edit ainsi que Save fonctions du plugin de bloc.

  • La Edit La fonction rend le contenu en fonction de ce que vous voulez voir dans l'éditeur de blocs. Vous pouvez avoir des composants React interactifs ici.
  • La Save La fonction rend le contenu en fonction de ce que vous voulez voir sur le front-end. Vous ne pouvez pas avoir les composants React réguliers ou les crochets ici. Il est utilisé pour renvoyer le code HTML statique enregistré dans votre base de données avec les attributs.

La Save la fonction est l'endroit où nous traînons aujourd'hui. Nous pouvons créer des composants interactifs sur le front-end, mais pour cela, nous devons les inclure manuellement et y accéder en dehors du Save fonction dans un fichier comme nous l'avons fait dans le dernier article.

Donc, je vais couvrir le même terrain que nous avons fait dans le dernier article, mais cette fois, vous pouvez voir l'aperçu dans l'éditeur de blocs before vous le publiez sur le front-end.

Les accessoires de bloc

J'ai intentionnellement omis toute explication sur le edit les accessoires de la fonction dans le dernier article, car cela aurait détourné l'attention du point principal, le rendu.

Si vous venez d'un milieu React, vous comprendrez probablement de quoi je parle, mais si vous êtes nouveau dans ce domaine, je recommanderais vérifier les composants et les accessoires dans la documentation de React.

Si nous enregistrons le props objet à la console, il renvoie une liste de fonctions et de variables WordPress liées à notre bloc :

Rendu des données d'API externes dans des blocs WordPress sur le back-end

Nous n'avons besoin que de attributes objet et le setAttributes fonction que je vais déstructurer de la props objet dans mon code. Dans le dernier article, j'avais modifié le code de RapidAPI afin de pouvoir stocker les données de l'API via setAttributes(). Les accessoires sont uniquement lisibles, nous ne pouvons donc pas les modifier directement.

Les accessoires de bloc sont similaires aux variables d'état et setState dans React, mais React fonctionne côté client et setAttributes() est utilisé pour stocker les attributs de manière permanente dans la base de données WordPress après avoir enregistré la publication. Donc, ce que nous devons faire, c'est les enregistrer pour attributes.data puis appelez cela comme la valeur initiale pour le useState() variable.

La edit fonction

Je vais copier-coller le code HTML que nous avons utilisé dans football-rankings.php dans le dernier article et modifiez-le un peu pour passer à l'arrière-plan JavaScript. Rappelez-vous comment nous avons créé deux fichiers supplémentaires dans le dernier article pour le style et les scripts frontaux ? Avec la façon dont nous abordons les choses aujourd'hui, il n'est pas nécessaire de créer ces fichiers. Au lieu de cela, nous pouvons tout déplacer vers le Edit la fonction.

Code complet
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}
Rendering External API Data in WordPress Blocks on the Back End PlatoBlockchain Data Intelligence. Vertical Search. Ai.
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => { return (
{result}
); })}
); } )}
)}
); }

J'ai inclus le crochet React useState() de @wordpress/element plutôt que de l'utiliser à partir de la bibliothèque React. En effet, si je chargeais de manière habituelle, il téléchargerait React pour chaque bloc que j'utilise. Mais si j'utilise @wordpress/element il se charge à partir d'une source unique, c'est-à-dire la couche WordPress au-dessus de React.

Cette fois, je n'ai pas non plus enveloppé le code à l'intérieur useEffect() mais à l'intérieur d'une fonction qui n'est appelée qu'en cliquant sur un bouton afin que nous ayons un aperçu en direct des données récupérées. J'ai utilisé une variable d'état appelée apiData pour rendre le classement conditionnel. Donc, une fois que le bouton est cliqué et que les données sont récupérées, je paramètre apiData aux nouvelles données à l'intérieur du fetchData() et il y a un rendu avec le HTML du tableau de classement du football disponible.

Vous remarquerez qu'une fois la publication enregistrée et la page actualisée, le tableau de classement a disparu. C'est parce que nous utilisons un état vide (null) Pour apiDatala valeur initiale de . Lorsque la publication est enregistrée, les attributs sont enregistrés dans le attributes.data objet et nous l'appelons comme la valeur initiale pour le useState() variable comme ceci :

const [apiData, setApiData] = useState(attributes.data);

La save fonction

Nous allons faire presque exactement la même chose avec le save fonction, mais modifiez-la un peu. Par exemple, il n'y a pas besoin du bouton "Récupérer les données" sur le front-end, et le apiData La variable d'état est également inutile car nous la vérifions déjà dans le edit fonction. Mais nous avons besoin d'un hasard apiData variable qui vérifie attributes.data pour restituer conditionnellement le JSX, sinon il générera des erreurs indéfinies et l'interface utilisateur de l'éditeur de blocs deviendra vide.

Code complet
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}
Rendering External API Data in WordPress Blocks on the Back End PlatoBlockchain Data Intelligence. Vertical Search. Ai.
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => { return (
{result}
); })}
); })}
)} ); }

Si vous modifiez le save fonction après qu'un bloc est déjà présent dans l'éditeur de blocs, il afficherait une erreur comme celle-ci :

Le bloc de classement du football dans l'éditeur de blocs WordPress avec un message d'erreur indiquant que le bloc contient une erreur inattendue.
Rendu des données d'API externes dans des blocs WordPress sur le back-end

En effet, le balisage du contenu enregistré est différent du balisage de notre nouveau save fonction. Puisque nous sommes en mode développement, il est plus facile de supprimer le bloc de la page actuelle et de le réinsérer en tant que nouveau bloc - de cette façon, le code mis à jour est utilisé à la place et les choses sont de nouveau synchronisées.

Cette situation de le supprimer et de l'ajouter à nouveau peut être évitée si nous avions utilisé le render_callback puisque la sortie est dynamique et contrôlée par PHP au lieu de la fonction save. Ainsi, chaque méthode a ses propres avantages et inconvénients.

Tom Nowell fournit une explication détaillée sur ce qu'il ne faut pas faire dans un save fonctionner dans ce débordement de pile répondre.

Styliser le bloc dans l'éditeur et le front-end

En ce qui concerne le style, ce sera presque la même chose que nous avons vue dans le dernier article, mais avec quelques modifications mineures que j'ai expliquées dans les commentaires. Je ne fais que fournir les styles complets ici, car il ne s'agit que d'une preuve de concept plutôt que de quelque chose que vous souhaitez copier-coller (à moins que vous n'ayez vraiment besoin d'un bloc pour afficher les classements de football dans un style similaire). Et notez que j'utilise toujours SCSS qui se compile en CSS lors de la construction.

Styles de l'éditeur
/* 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);
    }
  }
}
Styles frontaux
/* 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;
    }
  }
}

Nous ajoutons ceci à src/style.scss qui s'occupe du style à la fois dans l'éditeur et dans l'interface. Je ne pourrai pas partager l'URL de la démo car cela nécessiterait un accès éditeur, mais j'ai enregistré une vidéo pour que vous puissiez voir la démo :


Plutôt chouette, non ? Nous avons maintenant un bloc entièrement fonctionnel qui non seulement s'affiche sur le front-end, mais récupère également les données de l'API et s'affiche directement dans l'éditeur de blocs - avec un bouton d'actualisation pour démarrer !

Mais si nous voulons prendre plein avantage de l'éditeur de blocs WordPress, nous devrions envisager de mapper certains des éléments de l'interface utilisateur du bloc à bloquer les contrôles pour des choses comme la définition de la couleur, de la typographie et de l'espacement. C'est une belle prochaine étape dans le parcours d'apprentissage du développement de blocs.

Horodatage:

Plus de Astuces CSS