Representación de datos de API externas en bloques de WordPress en el front-end | consejos CSS

Ha habido nuevos tutoriales de CSS-Tricks 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 guardarlos en WordPress para usarlos en páginas y publicaciones.

Si bien los conceptos básicos del boulder están bien cubiertos en esta publicación, quiero dar otro paso adelante. Verá, en este artículo, aprendimos la diferencia entre renderizar bloques en el editor de bloques de WordPress de back-end y renderizarlos en el tema de front-end. El ejemplo era un bloque Pullquote simple que presentaba diferentes contenidos y estilos en cada extremo.

Vayamos más allá y veamos cómo usar contenido dinámico en un bloque de WordPress. Específicamente, obtengamos datos de una API externa y representémoslos en el front-end cuando un bloque en particular se coloca en el editor de bloques.

Vamos a construir un bloque que genere datos que muestren fútbol (uh, Fútbol) rankings tomados de Api-Football.

Un conjunto ordenado de clasificaciones de equipos de fútbol que muestra los logotipos, nombres y resultados de los equipos.
Por eso trabajamos juntos.

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

Inicializando nuestro complemento de bloque

Lo primero es lo primero: comencemos un nuevo proyecto desde la línea de comandos:

npx @wordpress/create-block football-rankings

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

Una vez que el comando ha creado la carpeta del proyecto, técnicamente tenemos un bloque de WordPress completamente funcional guardado como un complemento. Entonces, avancemos y sueltemos la carpeta del proyecto en el wp-content/plugins directorio donde instaló WordPress (probablemente mejor para trabajar en un entorno local), luego inicie sesión en el administrador de WordPress y actívelo desde la pantalla Complementos.

Ahora que nuestro bloque está inicializado, instalado y activado, continúe y abra la carpeta del proyecto desde /wp-content/plugins/football-rankings. vas a querer cd allí también 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 por ahora:

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

Los otros archivos del proyecto son importantes, por supuesto, pero no esenciales en este punto.

Revisión de la fuente de la API

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

Una interfaz de tablero con tres columnas que muestran código y datos de una fuente de API.
El panel de RapidAPI

Si desea echar un vistazo a la estructura JSON, puede generar una representación visual con JSONCrack.

Recuperación de datos de edit.js carpetas

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

Aquí está el código donde importo useEffect()luego envolviéndolo alrededor del 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>
  );
}

Fíjate que dejé el return funciona prácticamente intacto, pero he incluido una nota que confirma que la clasificación de fútbol se representa en el frente. Una vez más, en este artículo solo nos vamos a centrar en el front-end; también podríamos representar 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 que estamos obteniendo datos, necesitamos almacenarlos en algún lugar de WordPress. Aquí es donde el attributes.data el objeto es práctico. Definimos el data.type en tanto que object ya que los datos se recuperan y se formatean en JSON. Asegúrese de no tener ningún otro tipo, de lo contrario, WordPress no registrará datos ni arrojará errores para depurar.

Definimos todo esto en nuestro index.js carpetas:

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

Bien, ahora WordPress sabe que los datos de RapidAPI que estamos obteniendo 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 ahora se almacenan 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.

Mostrar una cadena de salida JSON grande en una tabla de base de datos.
Salida API almacenada en la base de datos de WordPress

Salida de datos JSON en el front-end

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

Me gusta mantener una separación de preocupaciones, así que la forma en que hago esto es agregar dos archivos nuevos al complemento de bloque build carpetas: frontend.js y frontend.css (puedes crear un frontend.scss carpeta en el src directorio compilado en CSS en el build directorio telefónico). De esta forma, los códigos back-end y front-end se separan y el football-rankings.php El archivo es un poco más fácil de leer.

/explicación Refiriéndose a la Introducción al desarrollo de bloques de WordPress, hay editor.css y style.css archivos para el back-end y estilos compartidos entre front-end y back-end, respectivamente. Agregando 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 en 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();
}

Ya que uso el render_callback() método para los atributos, manejaré la cola manualmente, como sugiere el manual del editor de bloques. Está contenido en el !is_admin() y pone en cola ambos archivos para evitar ponerlos en cola al usar la pantalla del editor.

Ahora que tenemos dos archivos nuevos a los que llamamos, debemos asegurarnos de decir npm para compilarlos. Así que haz esto en package.jsonen el 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 los archivos es definiéndolos en el bloque de metadatos contenidos en nuestro block.json archivo, como se muestra en la introducción al desarrollo de bloques:

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

La única razón por la que voy con el package.json método es porque ya uso el render_callback() método.

Representación de datos JSON

En la parte renderizada, solo me enfoco 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 ID de bloque específico.

Básicamente voy a esperar a que la ventana se cargue y obtenga datos de algunos objetos JSON clave y los aplicaré a algún marcado que lo muestre en el front-end. También convertiré el attributes datos a un objeto JSON para que sea más fácil leer JavaScript y establecer detalles de JSON a HTML para elementos como el logotipo de la liga de fútbol, ​​los logotipos del equipo y las estadísticas.

La columna "Últimos 5 partidos" muestra los resultados de los últimos cinco partidos de un equipo. Tengo que editar manualmente los datos porque los datos de la API están en formato de cadena. Convertirlo en una tabla puede ayudar a usarlo en HTML como un elemento separado para cada uno de los últimos cinco juegos de un 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 quieres trabajar con algo, tengo un conjunto completo de estilos que puedes usar como punto de partida.

He estado diseñando cosas en SCSS desde el @wordpress/create-block el paquete lo admite fuera de la caja. Correr npm run start en la línea de comandos para ver los archivos SCSS y compilarlos en CSS al guardarlos. Como alternativa, puede utilizar npm run build en cada guardado para compilar el SCSS y construir el resto del paquete 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!

Compruébalo: acabamos de crear un complemento de bloque que obtiene datos y los muestra en el front-end de un sitio de WordPress.

Encontramos una API, fetch()Editó los datos, los guardó en la base de datos de WordPress, los analizó y los aplicó al marcado HTML para mostrarlos en el front-end. No está mal para un solo tutorial, ¿verdad?

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

Si quieres conocer otros artículos parecidos a Representación de datos de API externas en bloques de WordPress en el front-end | consejos CSS puedes visitar la categoría Estilo.

Deja un comentario

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

Subir

Esta página web utiliza cookies para analizar de forma anónima y estadística el uso que haces de la web, mejorar los contenidos y tu experiencia de navegación. Para más información accede a la Política de Cookies . Ver mas