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 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.
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.
Om du vill ta en titt på JSON-strukturen kan du generera visuell representation med JSONCrack.
edit.js
fil
Hämtar data från 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.
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(); ?>
RankLogoTeam nameGPGWGDGLGFGAPtsLast 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 ipackage.json
Iscripts
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 avrender_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 }`; // 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 ); }); });${ played }${ win }${ draw }${ lose }${ goals.for }${ goals.against }${ team.points }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. Springanpm run start
på kommandoraden för att titta på SCSS-filerna och kompilera dem till CSS vid spara. Alternativt kan du användanpm 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.