Renderizando dados externos de API em blocos WordPress no Front End PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Renderizando dados de API externos em blocos do WordPress no front-end

Houve alguns novos tutoriais surgindo aqui no CSS-Tricks para trabalhar com blocos do WordPress. Um deles é uma introdução ao desenvolvimento de blocos do WordPress e é um bom lugar para aprender o que são blocos e registrá-los no WordPress para uso em páginas e posts.

Embora o básico do bloco seja bem abordado nesse post, quero dar mais um passo à frente. Você vê, nesse artigo, aprendemos a diferença entre renderizar blocos no WordPress Block Editor de back-end e renderizá-los no tema de front-end. O exemplo foi um simples Pullquote Block que renderizava conteúdo e estilos diferentes em cada extremidade.

Vamos mais longe e veja como usar conteúdo dinâmico em um bloco do WordPress. Mais especificamente, vamos buscar dados de uma API externa e renderizá-los no front-end quando um bloco específico for solto no Editor de blocos.

Vamos construir um bloco que gera dados que mostram futebol (er, futebol) classificações extraídas de Api-Futebol.

É para isso que estamos trabalhando juntos.

Há mais de uma maneira de integrar uma API com um bloco do WordPress! Como o artigo sobre noções básicas de blocos já percorreu o processo de fazer um bloco do zero, vamos simplificar as coisas usando o @wordpress/create-block pacote para inicializar nosso trabalho e estruturar nosso projeto.

Inicializando nosso plugin de bloco

Primeiras coisas primeiro: vamos criar um novo projeto a partir da linha de comando:

npx @wordpress/create-block football-rankings

Eu normalmente iniciaria um projeto como esse criando os arquivos do zero, mas parabéns à equipe do WordPress Core por este utilitário útil!

Uma vez que a pasta do projeto foi criada pelo comando, tecnicamente temos um bloco WordPress totalmente funcional registrado como um plugin. Então, vamos em frente e solte a pasta do projeto no wp-content/plugins diretório em que você instalou o WordPress (provavelmente é melhor trabalhar em um ambiente local), faça login no administrador do WordPress e ative-o na tela Plugins.

Renderizando dados externos de API em blocos WordPress no Front End PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Renderizando dados de API externos em blocos do WordPress no front-end

Agora que nosso bloco está inicializado, instalado e ativado, vá em frente e abra a pasta do projeto em /wp-content/plugins/football-rankings. Você vai querer cd lá da linha de comando também para garantir que possamos continuar o desenvolvimento.

Estes são os únicos arquivos nos quais precisamos nos concentrar no momento:

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

Os outros arquivos do projeto são importantes, é claro, mas não são essenciais neste momento.

Revisando a origem da API

Já sabemos que estamos usando Api-Futebol que chega até nós cortesia de API rápida. Felizmente, o RapidAPI tem um painel que gera automaticamente os scripts necessários que precisamos para buscar os dados da API para a classificação da Premier League de 2021.

Uma interface de painel com três colunas mostrando código e dados de uma fonte de API.
O painel do RapidAPI

Se você quiser dar uma olhada na estrutura JSON, você pode gerar uma representação visual com JSON Crack.

Buscando dados do edit.js lima

Vou envolver o código RapidAPI dentro de um Reagir useEffect() gancho com uma matriz de dependência vazia para que seja executada apenas uma vez quando a página for carregada. Dessa forma, evitamos que o WordPress chame a API toda vez que o Block Editor for renderizado novamente. Você pode verificar isso usando wp.data.subscribe() se você se importa.

Aqui está o código onde estou importando useEffect(), em seguida, envolvendo-o ao redor do fetch() código fornecido pelo 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 (
    

{ __( "Standings loaded on the front end", "external-api-gutenberg" ) }

); }

Observe que eu deixei o return função praticamente intacta, mas incluímos uma nota que confirma que as classificações de futebol são renderizadas no front-end. Novamente, vamos nos concentrar apenas no front-end neste artigo - também podemos renderizar os dados no Block Editor, mas deixaremos isso para outro artigo para manter o foco.

Armazenando dados da API no WordPress

Agora que estamos buscando dados, precisamos armazená-los em algum lugar no WordPress. É aqui que o attributes.data objeto vem a calhar. Estamos definindo o data.type como object uma vez que os dados são buscados e formatados como JSON. Certifique-se de que você não tenha nenhum outro tipo ou então o WordPress não salvará os dados, nem lançará nenhum erro para você depurar.

Definimos tudo isso em nosso index.js arquivo:

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

OK, então o WordPress agora sabe que os dados RapidAPI que estamos buscando são um objeto. Se abrirmos um novo rascunho de postagem no WordPress Block Editor e salvarmos a postagem, os dados agora serão armazenados no banco de dados. De fato, se pudermos ver isso no wp_posts.post_content campo se abrirmos o banco de dados do site no phpMyAdmin, Sequel Pro, Adminer ou qualquer ferramenta que você use.

Mostrando uma grande string de saída JSON em uma tabela de banco de dados.
Saída da API armazenada no banco de dados do WordPress

Saída de dados JSON no front-end

Existem várias maneiras de gerar os dados no front-end. A forma que vou mostrar pega os atributos que estão armazenados no banco de dados e os passa como parâmetro através do render_callback funcionar em nosso football-rankings.php arquivo.

Eu gosto de manter uma separação de preocupações, então como eu faço isso é adicionar dois novos arquivos ao plugin do bloco build pasta: frontend.js e frontend.css (você pode criar um frontend.scss arquivo no src diretório que compilou para CSS no build diretório). Desta forma, os códigos back-end e front-end são separados e os football-rankings.php arquivo é um pouco mais fácil de ler.

/explanation Voltando à introdução ao desenvolvimento de blocos do WordPress, existem editor.css e style.css arquivos para back-end e estilos compartilhados entre o front-end e o back-end, respectivamente. Adicionando frontend.scss (que compila para frontend.css, posso isolar estilos que são destinados apenas ao front-end.

Antes de nos preocuparmos com esses novos arquivos, veja como os chamamos 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(); ?>

  
        
      

Rank
Team name
GP
GW
GD
GL
GF
GA
Pts
Last 5 games

<?php return ob_get_clean();
}

Já que estou usando o render_callback() método para os atributos, vou lidar com o enfileiramento manualmente, assim como o O Manual do Editor de Blocos sugere. Isso está contido no !is_admin() condição, e está enfileirando os dois arquivos para que evitemos enfileirar enquanto usamos a tela do editor.

Agora que temos dois novos arquivos que estamos chamando, precisamos ter certeza de que estamos dizendo npm para compilá-los. Então, faça isso em package.json, Na scripts seção:

"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"
},

Outra forma de incluir os arquivos é defini-los nos metadados do bloco contidos em nosso block.json arquivo, como observado na introdução ao desenvolvimento de blocos:

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

A única razão pela qual estou indo com o package.json método é porque eu já estou fazendo uso do render_callback() método.

Renderizando os dados JSON

Na parte de renderização, estou me concentrando apenas em um único bloco. De um modo geral, você deseja segmentar vários blocos no front-end. Nesse caso, você precisa usar document.querySelectorAll() com o ID específico do bloco.

Basicamente, vou esperar a janela carregar e pegar dados para alguns objetos-chave do JSON e aplicá-los a alguma marcação que os renderize no front-end. Eu também vou converter o attributes data para um objeto JSON para que seja mais fácil ler o JavaScript e definir os detalhes de JSON para HTML para itens como o logotipo da liga de futebol, logotipos de times e estatísticas.

A coluna “Últimos 5 jogos” mostra o resultado dos últimos cinco jogos de uma equipe. Eu tenho que alterar manualmente os dados para isso, pois os dados da API estão em um formato de string. Convertê-lo em um array pode ajudar a usá-lo em HTML como um elemento separado para cada uma das últimas cinco partidas de uma equipe.

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 = `
      
${ index + 1 }
${ team.team.name }
${ played }
${ win }
${ draw }
${ lose }
${ goals.for }
${ goals.against }
${ team.points }
`; // 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 ); }); });

No que diz respeito ao estilo, você é livre para fazer o que quiser! Se você quiser algo para trabalhar, tenho um conjunto completo de estilos que você pode usar como ponto de partida.

Eu estilizei coisas em SCSS desde o @wordpress/create-block pacote o suporta fora da caixa. Corre npm run start na linha de comando para observar os arquivos SCSS e compilá-los para CSS ao salvar. Alternativamente, você pode usar npm run build em cada salvamento para compilar o SCSS e construir o resto do pacote de plugins.

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;

      & > 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 > div {
    width: 30px;
    text-align: center;
  }

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

  .form-history > 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;
  }
}

Aqui está a demonstração!

Confira - acabamos de criar um plug-in de bloco que busca dados e os renderiza no front-end de um site WordPress.

Encontramos uma API, fetch()-ed dados dele, salvou-o no banco de dados do WordPress, analisou-o e aplicou-o a alguma marcação HTML para exibir no front-end. Nada mal para um único tutorial, certo?

Novamente, podemos fazer o mesmo para que os rankings sejam renderizados no Editor de Blocos, além do front-end do tema. Mas espero que manter isso focado no front-end mostre como a busca de dados funciona em um bloco do WordPress e como os dados podem ser estruturados e renderizados para exibição.

Carimbo de hora:

Mais de Truques CSS