Representación de datos API externos en bloques de WordPress en el back-end PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Representación de datos de API externos en bloques de WordPress en el back-end

Esta es una continuación de mi último artículo sobre “Representación de datos de API externos en bloques de WordPress en el front-end”. En ese último, aprendimos cómo tomar una API externa e integrarla con un bloque que representa los datos obtenidos en el front-end de un sitio de WordPress.

La cuestión es que logramos esto de una manera que nos impide ver los datos en el Editor de bloques de WordPress. En otras palabras, podemos insertar el bloque en una página pero no obtenemos una vista previa. Solo podemos ver el bloque cuando se publica.

Revisemos el complemento de bloque de ejemplo que hicimos en el último artículo. Solo que esta vez, vamos a hacer uso del ecosistema JavaScript y React de WordPress para obtener y representar esos datos en el Editor de bloques de back-end también.

Donde dejamos

Mientras comenzamos esto, aquí hay una demostración donde aterrizamos en el último artículo al que puede hacer referencia. Habrás notado que usé un render_callback en el último artículo para que pueda hacer uso de los atributos en el archivo PHP y representar el contenido.

Bueno, eso puede ser útil en situaciones en las que podría tener que usar alguna función nativa de WordPress o PHP para crear bloques dinámicos. Pero si desea utilizar solo el ecosistema de JavaScript y React (JSX, específicamente) de WordPress para representar el HTML estático junto con los atributos almacenados en la base de datos, solo necesita concentrarse en el Edit y Save funciones del complemento de bloque.

  • El Edit La función representa el contenido en función de lo que desea ver en el Editor de bloques. Puede tener componentes React interactivos aquí.
  • El Save La función representa el contenido en función de lo que desea ver en la interfaz. No puede tener los componentes regulares de React o los ganchos aquí. Se utiliza para devolver el HTML estático que se guarda en su base de datos junto con los atributos.

El Save la función es donde estamos pasando el rato hoy. Podemos crear componentes interactivos en el front-end, pero para eso necesitamos incluirlos manualmente y acceder a ellos fuera del Save funcione en un archivo como lo hicimos en el último artículo.

Entonces, voy a cubrir el mismo tema que hicimos en el último artículo, pero esta vez puedes ver la vista previa en el Editor de bloques. antes lo publicas en el front-end.

Los accesorios de bloque

Intencionalmente omití cualquier explicación sobre el edit accesorios de la función en el último artículo porque eso habría desviado el enfoque del punto principal, la representación.

Si vienes de React, probablemente entenderás de qué estoy hablando, pero si eres nuevo en esto, te recomendaría revisando componentes y accesorios en la documentación de React.

Si registramos el props object a la consola, devuelve una lista de funciones y variables de WordPress relacionadas con nuestro bloque:

Representación de datos de API externos en bloques de WordPress en el back-end

Solo necesitamos el attributes objeto y el setAttributes función que voy a desestructurar a partir de la props objeto en mi código. En el último artículo, modifiqué el código de RapidAPI para poder almacenar los datos de la API a través de setAttributes(). Los accesorios solo se pueden leer, por lo que no podemos modificarlos directamente.

Los accesorios de bloque son similares a las variables de estado y setState en React, pero React funciona en el lado del cliente y setAttributes() se utiliza para almacenar los atributos de forma permanente en la base de datos de WordPress después de guardar la publicación. Entonces, lo que tenemos que hacer es guardarlos en attributes.data y luego llamarlo como el valor inicial para el useState() variable.

El edit función

Voy a copiar y pegar el código HTML que usamos en football-rankings.php en el último artículo y edítelo un poco para cambiar al fondo de JavaScript. ¿Recuerdas cómo creamos dos archivos adicionales en el último artículo para el estilo y las secuencias de comandos de la interfaz? Con la forma en que abordamos las cosas hoy, no hay necesidad de crear esos archivos. En su lugar, podemos mover todo a la Edit función.

Código completo
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}
); })}
); } )}
)}
); }

He incluido el gancho React useState() en @wordpress/element en lugar de usarlo desde la biblioteca React. Esto se debe a que si tuviera que cargar de forma normal, descargaría React para cada bloque que estoy usando. Pero si estoy usando @wordpress/element se carga desde una sola fuente, es decir, la capa de WordPress sobre React.

Esta vez, tampoco he envuelto el código dentro useEffect() pero dentro de una función que se llama solo al hacer clic en un botón para que tengamos una vista previa en vivo de los datos obtenidos. He usado una variable de estado llamada apiData para rendir la tabla de la liga condicionalmente. Entonces, una vez que se hace clic en el botón y se recuperan los datos, estoy configurando apiData a los nuevos datos dentro del fetchData() y hay un renderizado con el HTML de la tabla de clasificación de fútbol disponible.

Notarás que una vez que se guarda la publicación y se actualiza la página, la tabla de clasificación desaparece. Eso es porque estamos usando un estado vacío (null) para apiDatavalor inicial de . Cuando se guarda la publicación, los atributos se guardan en el attributes.data objeto y lo llamamos como el valor inicial para el useState() variable como esta:

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

El save función

Vamos a hacer casi exactamente lo mismo con el save función, pero modifíquelo un poco. Por ejemplo, no es necesario el botón "Obtener datos" en el frente, y el apiData La variable de estado también es innecesaria porque ya la estamos comprobando en el edit función. Pero necesitamos un aleatorio apiData variable que verifica attributes.data para representar condicionalmente el JSX o, de lo contrario, generará errores indefinidos y la interfaz de usuario del Editor de bloques quedará en blanco.

Código completo
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 está modificando el save función después de que un bloque ya está presente en el Editor de bloques, mostraría un error como este:

El bloque de clasificaciones de fútbol en el editor de bloques de WordPress con un mensaje de error que indica que el bloque contiene un error inesperado.
Representación de datos de API externos en bloques de WordPress en el back-end

Esto se debe a que el marcado en el contenido guardado es diferente del marcado en nuestro nuevo save función. Dado que estamos en modo de desarrollo, es más fácil eliminar el bloque de la página actual y volver a insertarlo como un bloque nuevo; de esa manera, se usa el código actualizado y las cosas vuelven a estar sincronizadas.

Esta situación de quitarlo y volverlo a poner se puede evitar si hubiésemos utilizado el render_callback ya que la salida es dinámica y controlada por PHP en lugar de la función de guardar. Así que cada método tiene sus propias ventajas y desventajas.

Tom Nowell brinda una explicación detallada sobre lo que no se debe hacer en un save Funcionar en este desbordamiento de pila https://www.youtube.com/watch?v=xB-eutXNUMXJtA&feature=youtu.be.

Diseñar el bloque en el editor y el front-end

Con respecto al estilo, será casi lo mismo que vimos en el último artículo, pero con algunos cambios menores que expliqué en los comentarios. Simplemente proporciono los estilos completos aquí, ya que esto es solo una prueba de concepto en lugar de algo que desea copiar y pegar (a menos que realmente necesite un bloque para mostrar clasificaciones de fútbol con este estilo). Y tenga en cuenta que todavía estoy usando SCSS que se compila en CSS en la compilación.

Estilos del editor
/* 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);
    }
  }
}
Estilos de front-end
/* 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;
    }
  }
}

Agregamos esto a src/style.scss que se encarga del estilo tanto en el editor como en la interfaz. No podré compartir la URL de demostración ya que requeriría acceso de editor, pero tengo un video grabado para que pueda ver la demostración:


Bastante ordenado, ¿verdad? Ahora tenemos un bloque en pleno funcionamiento que no solo se procesa en la parte frontal, sino que también obtiene datos de API y se procesa allí mismo en el Editor de bloques, ¡con un botón de actualización para arrancar!

Pero si queremos tomar ser completados ventaja del editor de bloques de WordPress, deberíamos considerar asignar algunos de los elementos de la interfaz de usuario del bloque a controles de bloque para cosas como establecer el color, la tipografía y el espaciado. Ese es un buen siguiente paso en el viaje de aprendizaje del desarrollo de bloques.

Sello de tiempo:

Mas de Trucos CSS