Procesar datos de API externos en bloques front-end de WordPress | trucos CSS

Aquí hay algunos tutoriales nuevos sobre trucos de CSS para trabajar con bloques de WordPress. Uno de ellos es una introducción al desarrollo de bloques de WordPress y es un buen lugar para aprender qué son los bloques y registrarlos en WordPress para usarlos en páginas y publicaciones.

Si bien los conceptos básicos de los bloques están bien cubiertos en esta publicación, quiero ir un paso más allá. Verá, en este artículo aprendimos la diferencia entre renderizar bloques en el back-end del Editor de bloques de WordPress y renderizarlos en el front-end. El ejemplo fue un bloque Pullquote simple que renderiza diferentes contenidos y estilos desde cada extremo.

Vayamos más allá y veamos el uso. contenido dinámico en un bloque de WordPress Específicamente, recuperemos datos de una API externa y representémoslos en la interfaz cuando un bloque en particular se coloque en el Editor de bloques.

Vamos a construir un bloque que genere datos que muestren fútbol (uhh, fútbol) clasificaciones derivadas de Api-Fútbol.

Esto es por lo que estamos trabajando juntos.

¡Hay más de una forma de integrar una API con un bloque de WordPress! Dado que el artículo de conceptos básicos de bloques ya cubrió el proceso de creación de un bloque desde cero, simplificaremos las cosas usando @wordpress/create-block paquete para iniciar nuestro trabajo y estructurar nuestro proyecto.

Inicializando nuestro complemento de bloque

Primero: comencemos un nuevo proyecto desde la línea de comando:

npx @wordpress/create-block football-rankings

Normalmente comenzaría un proyecto como este haciendo los archivos desde cero, ¡pero felicitaciones al equipo central de WordPress por esta práctica utilidad!

Una vez que el comando crea la carpeta del proyecto, técnicamente tenemos un bloque de WordPress completamente funcional registrado como un complemento. Así que sigamos y sueltemos la carpeta del proyecto en el wp-content/plugins directorio donde instaló WordPress (probablemente es mejor ejecutarlo en un entorno local), luego inicie sesión en su administrador de WordPress y habilítelo desde la pantalla de complementos.

Ahora que nuestro bloque está inicializado, instalado y habilitado, continúe y abra la carpeta del proyecto desde en /wp-content/plugins/football-rankingsquerrás cd allí y desde la línea de comandos para asegurarnos de que podemos continuar con el desarrollo.

Estos son los únicos archivos en los que debemos centrarnos en este momento:

  • edit.js
  • index.js
  • football-rankings.php

Los otros archivos del proyecto son importantes, por supuesto, pero no esenciales en esta etapa.

Ver la fuente de la API

Ya sabemos que usamos Api-Fútbol que nos llega por cortesía de API rápidaAfortunadamente, RapidAPI tiene un tablero que genera automáticamente los scripts necesarios que necesitamos para obtener los datos de la API para la clasificación de la Premier League de 2021.

Una interfaz de tablero de tres columnas que muestra el código fuente y los datos de la API.
Tablero RapidAPI

Si desea ver la estructura JSON, puede generar una representación visual con JSONCrack.

Recuperar datos de edit.js expediente

Envolveré el código RapidAPI en un Reaccionar useEffect() gancho con una matriz de dependencia vacía para que se ejecute solo una vez cuando se carga la página. De esta forma evitamos que WordPress llame a la API cada vez que se vuelve a renderizar el editor de bloques. Puedes verificar esto usando wp.data.subscribe() si te importa.

Aquí está el código donde importo useEffect()luego envuélvelo fetch() código proporcionado por RapidAPI:

/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
*
* @return {WPElement} Element to render.
*/

import { useEffect } from "@wordpress/element";

export default function Edit(props) {
  const { attributes, setAttributes } = props;

  useEffect(() => {
    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 };
        setAttributes( { data: newData } );
        console.log( "Attributes", attributes );
      })
      .catch((err) => console.error(err));
}, []);

  return (
    <p { ...useBlockProps() }>
      { __( "Standings loaded on the front end", "external-api-gutenberg" ) }
    </p>
  );
}

Aviso que me fui return funcionan casi intactos, pero han incluido una nota que confirma que la clasificación de fútbol se muestra en la parte delantera. Una vez más, en este artículo solo nos centraremos en la interfaz; también podemos representar los datos en el editor de bloques, pero lo dejaremos para otro artículo para mantener las cosas enfocadas.

Almacenamiento de datos API en WordPress

Ahora, cuando recuperamos datos, debemos almacenarlos en algún lugar de WordPress. Aquí es donde attributes.data el objeto es útil. Definimos data.type me gusta object ya que los datos se extraen y se formatean como JSON. Asegúrese de no tener ningún otro tipo, de lo contrario, WordPress no guardará los datos ni arrojará un error para depurar.

Definimos todo esto en nuestro index.js expediente:

registerBlockType( metadata.name, {
  edit: Edit,
  attributes: {
    data: {
      type: "object",
    },
  },
  save,
} );

Bien, ahora WordPress sabe que los datos de RapidAPI que estamos recuperando son un objeto. Si abrimos un nuevo borrador de publicación en el editor de bloques de WordPress y guardamos la publicación, los datos ya están almacenados en la base de datos. De hecho, si podemos verlo en wp_posts.post_content campo si abrimos la base de datos del sitio en phpMyAdmin, Sequel Pro, Adminer, o cualquier otra herramienta que utilice.

Muestra una gran cadena de salida JSON en una tabla de base de datos.
Salida API almacenada en la base de datos de WordPress

Salida de datos JSON al front-end

Hay varias formas de mostrar los datos en el front-end. La forma en que les voy a mostrar toma los atributos que están almacenados en la base de datos y los pasa como un parámetro a través de render_callback funcionar en nuestro football-rankings.php expediente.

Me gusta mantener los problemas separados, así que, ¿cómo lo hago? esto es para agregar dos nuevos archivos al complemento de bloqueo build carpeta: frontend.js y frontend.css (puedes crear un frontend.scss presentar en src directorio que se compila en css en build Por lo tanto, el código subyacente y el código frontal están separados y football-rankings.php El archivo es un poco más fácil de leer.

/explicación Volviendo a la introducción al desarrollo de bloques de WordPress, hay editor.css y style.css archivos de back-end y estilos compartidos entre front-end y back-end, respectivamente. por adición frontend.scss (que compila a frontend.cssPuedo aislar estilos que solo están destinados al front-end.

Antes de preocuparnos por estos nuevos archivos, así es como los llamamos football-rankings.php:

/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function create_block_football_rankings_block_init() {
  register_block_type( __DIR__ . '/build', array(
    'render_callback' => 'render_frontend'
  ));
}
add_action( 'init', 'create_block_football_rankings_block_init' );

function render_frontend($attributes) {
  if( !is_admin() ) {
    wp_enqueue_script( 'football_rankings', plugin_dir_url( __FILE__ ) . '/build/frontend.js');
    wp_enqueue_style( 'football_rankings', plugin_dir_url( __FILE__ ) . '/build/frontend.css' ); // HIGHLIGHT 15,16,17,18
  }
  
  ob_start(); ?>

  <div class="football-rankings-frontend" id="league-standings">
    <div class="data">
      <pre>
        <?php echo wp_json_encode( $attributes ) ?>
      </pre>
    </div>
    <div class="header">
      <div class="position">Rank</div>
      <div class="team-logo">Logo</div>
      <div class="team-name">Team name</div>
      <div class="stats">
        <div class="games-played">GP</div>
        <div class="games-won">GW</div>
        <div class="games-drawn">GD</div>
        <div class="games-lost">GL</div>
        <div class="goals-for">GF</div>
        <div class="goals-against">GA</div>
        <div class="points">Pts</div>
      </div>
      <div class="form-history">Last 5 games</div>
    </div>
    <div class="league-table"></div>
  </div>

  <?php return ob_get_clean();
}

Desde que uso render_callback() método para los atributos, manejaré la cola manualmente como El manual del editor de bloques ofreceEsto está contenido en !is_admin() state y pone en cola los dos archivos para que evitemos ponerlos en cola mientras usamos la pantalla del editor.

Ahora que tenemos dos archivos nuevos a los que llamamos, debemos asegurarnos de decir npm para compilarlos. Entonces, haz esto en package.jsonen scripts sección:

"scripts": {
  "build": "wp-scripts build src/index.js src/frontend.js",
  "format": "wp-scripts format",
  "lint:css": "wp-scripts lint-style",
  "lint:js": "wp-scripts lint-js",
  "packages-update": "wp-scripts packages-update",
  "plugin-zip": "wp-scripts plugin-zip",
  "start": "wp-scripts start src/index.js src/frontend.js"
},

Otra forma de incluir archivos es definiéndolos en el bloque de metadatos contenidos en nuestro block.json archivo como se indica en la introducción de bloqueo de desarrollo:

"viewScript": [ "file:./frontend.js", "example-shared-view-script" ],
"style": [ "file:./frontend.css", "example-shared-style" ],

La única razón para ir con package.json método es porque ya estoy usando render_callback() método.

Representación de datos JSON

En la parte de renderizado, me concentro en un solo bloque. En términos generales, le gustaría apuntar a múltiples bloques en el front-end. En este caso debes usar document.querySelectorAll() con el identificador específico del bloque.

Básicamente, esperaré a que se cargue la ventana y tomaré algunos datos de objetos clave del JSON y los aplicaré a algún marcado que los represente en la interfaz. yo también convertiré attributes datos en un objeto JSON para que sea más fácil leer a través de JavaScript y configurar los detalles de JSON a HTML para elementos como logotipos de ligas de fútbol, ​​logotipos de equipos y estadísticas.

La columna de los últimos 5 juegos muestra el resultado de los últimos cinco juegos del equipo. Tengo que cambiar manualmente los datos porque los datos de la API están en formato de cadena. Convertirlos en una matriz puede ayudar a usarlos en HTML como un elemento separado para cada uno de los últimos cinco partidos del equipo.

import "./frontend.scss";

// Wait for the window to load
window.addEventListener( "load", () => {
  // The code output
  const dataEl = document.querySelector( ".data pre" ).innerHTML;
  // The parent rankings element
  const tableEl = document.querySelector( ".league-table" );
  // The table headers
  const tableHeaderEl = document.querySelector( "#league-standings .header" );
  // Parse JSON for the code output
  const dataJSON = JSON.parse( dataEl );
  // Print a little note in the console
  console.log( "Data from the front end", dataJSON );
  
  // All the teams 
  let teams = dataJSON.data.response[ 0 ].league.standings[ 0 ];
  // The league logo
  let leagueLogoURL = dataJSON.data.response[ 0 ].league.logo;
  // Apply the league logo as a background image inline style
  tableHeaderEl.style.backgroundImage = `url( ${ leagueLogoURL } )`;
  
  // Loop through the teams
  teams.forEach( ( team, index ) => {
    // Make a div for each team
    const teamDiv = document.createElement( "div" );
    // Set up the columns for match results
    const { played, win, draw, lose, goals } = team.all;

    // Add a class to the parent rankings element
    teamDiv.classList.add( "team" );
    // Insert the following markup and data in the parent element
    teamDiv.innerHTML = `
      <div class="position">
        ${ index + 1 }
      </div>
      <div class="team-logo">
        <img src="https://css-tricks.com/rendering-external-api-data-in-wordpress-blocks-on-the-front-end/${ team.team.logo }" />
      </div>
      <div class="team-name">${ team.team.name }</div>
      <div class="stats">
        <div class="games-played">${ played }</div>
        <div class="games-won">${ win }</div>
        <div class="games-drawn">${ draw }</div>
        <div class="games-lost">${ lose }</div>
        <div class="goals-for">${ goals.for }</div>
        <div class="goals-against">${ goals.against }</div>
        <div class="points">${ team.points }</div>
      </div>
      <div class="form-history"></div>
    `;
    
    // Stringify the last five match results for a team
    const form = team.form.split( "" );
    
    // Loop through the match results
    form.forEach( ( result ) => {
      // Make a div for each result
      const resultEl = document.createElement( "div" );
      // Add a class to the div
      resultEl.classList.add( "result" );
      // Evaluate the results
      resultEl.innerText = result;
      // If the result a win
      if ( result === "W" ) {
        resultEl.classList.add( "win" );
      // If the result is a draw
      } else if ( result === "D" ) {
        resultEl.classList.add( "draw" );
      // If the result is a loss
      } else {
        resultEl.classList.add( "lost" );
      }
      // Append the results to the column
      teamDiv.querySelector( ".form-history" ).append( resultEl );
    });

    tableEl.append( teamDiv );
  });
});

Cuando se trata de estilo, ¡eres libre de hacer lo que quieras! Si desea trabajar con algo, tengo un conjunto completo de estilos que puede usar como punto de partida.

Diseñé cosas en SCSS de @wordpress/create-block el paquete lo admite fuera de la caja npm run start en la línea de comando para ver los archivos SCSS y compilarlos en CSS al guardar. Como alternativa, puede utilizar npm run build en cada guardado para compilar SCSS y construir el resto del conjunto de complementos.

Ver SCSS

body {
  background: linear-gradient(to right, #8f94fb, #4e54c8);
}

.data pre {
  display: none;
}

.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-repeat: no-repeat;
  background-size: contain;
  background-position: right;
}

.frontend#league-standings {
  width: 900px;
  margin: 60px 0;
  max-width: unset;
  font-size: 16px;

  .header {
    .stats {
      display: flex;
      gap: 15px;

      &amp; &gt; 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;
  }

  .stats {
    display: flex;
    gap: 15px;
  }

  .stats &gt; div {
    width: 30px;
    text-align: center;
  }

  .form-history {
    display: flex;
    gap: 5px;
  }

  .form-history &gt; div {
    width: 25px;
    height: 25px;
    text-align: center;
    border-radius: 3px;
    font-size: 15px;
  }

  .form-history .win {
    background: #347d39;
    color: white;
  }

  .form-history .draw {
    background: gray;
    color: white;
  }

  .form-history .lost {
    background: lightcoral;
    color: white;
  }
}

¡Aquí está la demostración!

Mire esto: acabamos de crear un complemento de bloque que obtiene datos y los presenta en la parte frontal de un sitio de WordPress.

Encontramos una API, fetch()Extraje datos de él, los guardé en la base de datos de WordPress, los analicé y los apliqué a algunas marcas HTML para mostrarlas en la interfaz. No está mal para una lección, ¿verdad?

Nuevamente, podemos hacer lo mismo para que las clasificaciones se muestren en el editor de bloques además del front-end del tema. Pero es de esperar que mantener esto enfocado en la interfaz le muestre cómo funciona la extracción de datos en un bloque de WordPress y cómo se pueden estructurar y representar los datos para su visualización.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir