Rendering av extern API-data i WordPress-block på Front End PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Rendering av extern API-data i WordPress-block i användargränssnittet

Det har dykt upp några nya tutorials här om CSS-Tricks för att arbeta med WordPress-block. En av dem är en introduktion till WordPress blockutveckling och det är ett bra ställe att lära sig vad block är och att registrera dem i WordPress för användning i sidor och inlägg.

Även om grunderna för blocket är snyggt täckta i det inlägget, vill jag ta det ytterligare ett steg framåt. Du ser, i den artikeln lärde vi oss skillnaden mellan att rendera block i back-end WordPress Block Editor och att rendera dem på front-end-temat. Exemplet var ett enkelt Pullquote-block som återgav olika innehåll och stilar i varje ände.

Låt oss gå längre och titta på att använda dynamiskt innehåll i ett WordPress-block. Mer specifikt, låt oss hämta data från ett externt API och rendera det på fronten när ett visst block släpps i Block Editor.

Vi kommer att bygga ett block som matar ut data som visar fotboll (eh, fotboll) rankningar hämtade från Api-fotboll.

Det här är vad vi jobbar för tillsammans.

Det finns mer än ett sätt att integrera ett API med ett WordPress-block! Eftersom artikeln om blockgrunderna redan har gått igenom processen att göra ett block från början, kommer vi att förenkla saker och ting genom att använda @wordpress/create-block paket för att starta upp vårt arbete och strukturera vårt projekt.

Initierar vårt blockplugin

Första saker först: låt oss snurra upp ett nytt projekt från kommandoraden:

npx @wordpress/create-block football-rankings

Jag skulle vanligtvis sparka igång ett projekt som detta genom att göra filerna från början, men beröm till WordPress Core-teamet för detta praktiska verktyg!

När projektmappen har skapats av kommandot har vi tekniskt sett ett fullt fungerande WordPress-block registrerat som ett plugin. Så låt oss gå vidare och släppa projektmappen i wp-content/plugins katalog där du har WordPress installerat (förmodligen bäst att arbeta i en lokal miljö), logga sedan in på WordPress admin och aktivera den från plugins-skärmen.

Rendering av extern API-data i WordPress-block på Front End PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.
Rendering av extern API-data i WordPress-block i användargränssnittet

Nu när vårt block är initierat, installerat och aktiverat, gå vidare och öppna projektmappen från kl /wp-content/plugins/football-rankings. Du kommer att vilja cd där från kommandoraden också för att se till att vi kan fortsätta utvecklingen.

Det här är de enda filerna vi behöver koncentrera oss på för tillfället:

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

De andra filerna i projektet är naturligtvis viktiga, men är oväsentliga vid det här laget.

Granska API-källan

Vi vet redan att vi använder Api-fotboll som kommer till oss artighet av RapidAPI. Lyckligtvis har RapidAPI en instrumentpanel som automatiskt genererar de nödvändiga skripten vi behöver för att hämta API-data för 2021 års Premier League-ställning.

Ett instrumentpanelsgränssnitt med tre kolumner som visar kod och data från en API-källa.
RapidAPI-instrumentpanelen

Om du vill ta en titt på JSON-strukturen kan du generera visuell representation med JSONCrack.

Hämtar data från edit.js fil

Jag ska slå in RapidAPI-koden i en Reagera useEffect() krok med en tom beroendematris så att den bara körs en gång när sidan laddas. På så sätt förhindrar vi WordPress från att anropa API:t varje gång blockredigeraren återrenderar. Du kan kontrollera det med wp.data.subscribe() om du bryr dig.

Här är koden där jag importerar useEffect(), sedan vira den runt fetch() kod som RapidAPI gav:

/**
* 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" ) }

); }

Lägg märke till att jag har lämnat return fungerar i stort sett intakt, men har inkluderat en anteckning som bekräftar att fotbollsställningen återges på framsidan. Återigen, vi kommer bara att fokusera på gränssnittet i den här artikeln - vi skulle kunna återge data i Block Editor också, men vi lämnar det till en annan artikel för att hålla saker fokuserade.

Lagra API-data i WordPress

Nu när vi hämtar data måste vi lagra dem någonstans i WordPress. Det är här attributes.data objektet kommer väl till pass. Vi definierar data.type som en object eftersom data hämtas och formateras som JSON. Se till att du inte har någon annan typ, annars kommer WordPress inte att spara data, och det ger inte heller något fel för dig att felsöka.

Vi definierar allt detta i vår index.js fil:

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

OK, så WordPress vet nu att RapidAPI-datan vi hämtar är ett objekt. Om vi ​​öppnar ett nytt inläggsutkast i WordPress Block Editor och sparar inlägget, lagras nu data i databasen. Faktum är att om vi kan se det i wp_posts.post_content fältet om vi öppnar webbplatsens databas i phpMyAdmin, Sequel Pro, Adminer eller vilket verktyg du nu använder.

Visar en stor sträng av JSON-utdata i en databastabell.
API-utdata lagras i WordPress-databasen

Matar ut JSON-data i gränssnittet

Det finns flera sätt att mata ut data på gränssnittet. Sättet jag ska visa dig tar attributen som är lagrade i databasen och skickar dem som en parameter genom render_callback funktion i vår football-rankings.php fil.

Jag gillar att hålla en separation av bekymmer, så hur jag gör detta är att lägga till två nya filer till blockpluginens build mapp: frontend.js och frontend.css (du kan skapa en frontend.scss fil i src katalog som kompilerades till CSS i build katalog). På detta sätt är back-end- och front-end-koderna separata och football-rankings.php filen är lite lättare att läsa.

/explanation Med hänvisning till introduktionen till WordPress-blockutveckling finns det editor.css och style.css filer för back-end och delade stilar mellan front- och backend, respektive. Genom att lägga till frontend.scss (som kompilerar till frontend.css, jag kan isolera stilar som bara är avsedda för frontend.

Innan vi oroar oss för de nya filerna, så här kallar vi in ​​dem 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();
}

Eftersom jag använder render_callback() metod för attributen kommer jag att hantera kön manuellt precis som Block Editor Handbook föreslår. Det finns i !is_admin() condition, och ställer de två filerna i kö så att vi undviker att ställa dem i kö när vi använder redigeringsskärmen.

Nu när vi har två nya filer som vi ringer upp måste vi se till att vi berättar det npm att sammanställa dem. Så gör det i package.jsonI scripts avsnitt:

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

Ett annat sätt att inkludera filerna är att definiera dem i blockmetadata som finns i vår block.json fil, som noterat i introduktionen till blockutveckling:

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

Den enda anledningen till att jag går med package.json metoden beror på att jag redan använder mig av render_callback() metod.

Återger JSON-data

I renderingsdelen koncentrerar jag mig bara på ett enda block. Generellt sett skulle du vilja rikta in dig på flera block på frontend. I så fall måste du använda dig av document.querySelectorAll() med blockets specifika ID.

Jag kommer i princip att vänta på att fönstret ska laddas och ta tag i data för några nyckelobjekt från JSON och tillämpa dem på någon markering som återger dem på fronten. Jag kommer också att konvertera attributes data till ett JSON-objekt så att det är lättare att läsa igenom JavaScript och ställa in detaljerna från JSON till HTML för saker som fotbollsligans logotyp, laglogotyper och statistik.

Kolumnen "Senaste 5 matcherna" visar resultatet av ett lags senaste fem matcher. Jag måste manuellt ändra data för det eftersom API-data är i ett strängformat. Att konvertera det till en array kan hjälpa till att använda det i HTML som ett separat element för var och en av ett lags senaste fem matcher.

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 ); }); });

När det gäller styling är du fri att göra vad du vill! Om du vill ha något att jobba med har jag en komplett uppsättning stilar du kan använda som utgångspunkt.

Jag stylade saker i SCSS sedan @wordpress/create-block paketet stöder det ur förpackningen. Springa npm run start på kommandoraden för att titta på SCSS-filerna och kompilera dem till CSS vid spara. Alternativt kan du använda npm run build på varje spara för att kompilera SCSS och bygga resten av plugin-paketet.

Se 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;
  }
}

Här är demon!

Kolla in det - vi har precis skapat ett blockplugin som hämtar data och återger det på fronten av en WordPress-webbplats.

Vi hittade ett API, fetch()-ed data från den, sparade den i WordPress-databasen, analyserade den och applicerade den på någon HTML-uppmärkning för att visa på användargränssnittet. Inte illa för en enda handledning, eller hur?

Återigen kan vi göra samma sak så att rankningarna återges i blockredigeraren utöver temats frontend. Men att förhoppningsvis hålla detta fokuserat på gränssnittet visar dig hur hämtning av data fungerar i ett WordPress-block, och hur data kan struktureras och renderas för visning.

Tidsstämpel:

Mer från CSS-tricks