Det har dukket opp noen nye opplæringsprogrammer her om CSS-triks for å jobbe med WordPress-blokker. En av dem er en introduksjon til WordPress-blokkutvikling og det er et godt sted å lære hva blokker er og å registrere dem i WordPress for bruk i sider og innlegg.
Selv om det grunnleggende om blokken er godt dekket i det innlegget, vil jeg ta det enda et skritt fremover. Du skjønner, i den artikkelen lærte vi forskjellen mellom å gjengi blokker i back-end WordPress Block Editor og å gjengi dem på front-end-temaet. Eksemplet var en enkel Pullquote Block som gjengav forskjellig innhold og stiler i hver ende.
La oss gå videre og se på bruk dynamisk innhold i en WordPress-blokk. Mer spesifikt, la oss hente data fra et eksternt API og gjengi det på grensesnittet når en bestemt blokk slippes inn i Block Editor.
Vi skal bygge en blokk som sender ut data som viser fotball (eh, fotball) rangeringer hentet fra Api-fotball.
Det er mer enn én måte å integrere et API med en WordPress-blokk! Siden artikkelen om grunnleggende blokker allerede har gått gjennom prosessen med å lage en blokk fra bunnen av, skal vi forenkle ting ved å bruke @wordpress/create-block
pakke for å starte opp arbeidet vårt og strukturere prosjektet vårt.
Initialiserer blokkeringspluginen vår
Første ting først: la oss spinne opp et nytt prosjekt fra kommandolinjen:
npx @wordpress/create-block football-rankings
Jeg vil vanligvis sparke et prosjekt som dette i gang ved å lage filene fra bunnen av, men kudos til WordPress Core-teamet for dette hendige verktøyet!
Når prosjektmappen er opprettet av kommandoen, har vi teknisk sett en fullt funksjonell WordPress-blokk registrert som en plugin. Så la oss gå videre og slippe prosjektmappen inn i wp-content/plugins
katalogen der du har WordPress installert (sannsynligvis best å jobbe i et lokalt miljø), logg deretter inn på WordPress admin og aktiver den fra plugins-skjermen.
Nå som blokken vår er initialisert, installert og aktivert, fortsett og åpne opp prosjektmappen fra kl /wp-content/plugins/football-rankings
. Du kommer til å ville cd
der fra kommandolinjen også for å sikre at vi kan fortsette utviklingen.
Dette er de eneste filene vi trenger å konsentrere oss om for øyeblikket:
edit.js
index.js
football-rankings.php
De andre filene i prosjektet er selvfølgelig viktige, men er uvesentlige på dette tidspunktet.
Gjennomgang av API-kilden
Vi vet allerede at vi bruker Api-fotball som kommer til oss takket være RapidAPI. Heldigvis har RapidAPI et dashbord som automatisk genererer de nødvendige skriptene vi trenger for å hente API-dataene for 2021 Premier League-tabellen.
Hvis du vil ta en titt på JSON-strukturen, kan du generere visuell representasjon med JSONCrack.
edit.js
fil
Henter data fra Jeg skal pakke inn RapidAPI-koden i en Reager useEffect()
krok med en tom avhengighetsmatrise slik at den kjører bare én gang når siden er lastet. På denne måten forhindrer vi WordPress fra å kalle opp API hver gang Block Editor gjengis på nytt. Du kan sjekke det ved å bruke wp.data.subscribe()
hvis du bryr deg.
Her er koden jeg importerer useEffect()
, og deretter vikle den rundt fetch()
kode som RapidAPI ga:
/**
* 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" ) }
);
}
Legg merke til at jeg har forlatt return
fungerer stort sett intakt, men har inkludert et notat som bekrefter at fotballstillingene er gjengitt på frontenden. Igjen, vi skal bare fokusere på grensesnittet i denne artikkelen - vi kan også gjengi dataene i Block Editor, men vi lar det være til en annen artikkel for å holde ting fokusert.
Lagre API-data i WordPress
Nå som vi henter data, må vi lagre dem et sted i WordPress. Det er her attributes.data
objektet kommer godt med. Vi definerer data.type
som en object
siden dataene hentes og formateres som JSON. Pass på at du ikke har noen annen type, ellers vil ikke WordPress lagre dataene, og det gir heller ingen feil for deg å feilsøke.
Vi definerer alt dette i vår index.js
file:
registerBlockType( metadata.name, {
edit: Edit,
attributes: {
data: {
type: "object",
},
},
save,
} );
OK, så WordPress vet nå at RapidAPI-dataene vi henter er et objekt. Hvis vi åpner et nytt innleggsutkast i WordPress Block Editor og lagrer innlegget, lagres dataene nå i databasen. Faktisk, hvis vi kan se det i wp_posts.post_content
feltet hvis vi åpner nettstedets database i phpMyAdmin, Sequel Pro, Adminer eller hvilket verktøy du bruker.
Sender ut JSON-data i grensesnittet
Det er flere måter å sende ut data på frontend. Måten jeg skal vise deg tar attributtene som er lagret i databasen og sender dem som en parameter gjennom render_callback
funksjon i vår football-rankings.php
filen.
Jeg liker å holde en adskillelse av bekymringer, så hvordan jeg gjør dette er å legge til to nye filer til blokkeringspluginen build
mappe: frontend.js
og frontend.css
(du kan lage en frontend.scss
fil i src
katalogen som kompilerte til CSS i build
katalog). På denne måten er back-end- og front-end-kodene separate og football-rankings.php
filen er litt lettere å lese.
/explanation Med henvisning tilbake til introduksjonen til WordPress-blokkutvikling finnes det editor.css
og style.css
filer for back-end og delte stiler mellom henholdsvis front- og backend. Ved å legge til frontend.scss
(som kompilerer til frontend.css
, kan jeg isolere stiler som bare er ment for frontend.
Før vi bekymrer oss for de nye filene, her er hvordan vi kaller dem inn 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();
}Siden jeg bruker
render_callback()
metoden for attributtene, skal jeg håndtere køen manuelt akkurat som Block Editor Handbook foreslår. Det ligger i!is_admin()
tilstand, og setter de to filene i kø slik at vi unngår å sette dem i kø mens vi bruker redigeringsskjermen.Nå som vi har to nye filer vi ringer til, må vi sørge for at vi forteller det
npm
å kompilere dem. Så gjø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" },
En annen måte å inkludere filene på er å definere dem i blokkmetadataene i vår
block.json
fil, som notert i introduksjonen til blokkutvikling:"viewScript": [ "file:./frontend.js", "example-shared-view-script" ], "style": [ "file:./frontend.css", "example-shared-style" ],
Den eneste grunnen til at jeg går med
package.json
metoden er fordi jeg allerede brukerrender_callback()
metoden.Gjengir JSON-dataene
I gjengivelsesdelen konsentrerer jeg meg bare om en enkelt blokk. Generelt sett vil du målrette mot flere blokker på frontend. I så fall må du benytte deg av
document.querySelectorAll()
med blokkens spesifikke ID.Jeg kommer i utgangspunktet til å vente på at vinduet laster inn og hente data for noen få nøkkelobjekter fra JSON og bruke dem på noen markeringer som gjengir dem på frontenden. Jeg skal også konvertere
attributes
data til et JSON-objekt slik at det er lettere å lese gjennom JavaScript og sette detaljene fra JSON til HTML for ting som fotballigalogoen, laglogoer og statistikk.Kolonnen "Siste 5 kamper" viser resultatet av et lags siste fem kamper. Jeg må manuelt endre dataene for det siden API-dataene er i et strengformat. Konvertering av den til en array kan bidra til å bruke den i HTML som et separat element for hver av et lags siste fem kamper.
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 gjelder styling, står du fritt til å gjøre hva du vil! Hvis du vil ha noe å jobbe med, har jeg et komplett sett med stiler du kan bruke som utgangspunkt.
Jeg stylet ting i SCSS siden
@wordpress/create-block
pakken støtter det ut av esken. Løpenpm run start
på kommandolinjen for å se SCSS-filene og kompilere dem til CSS ved lagring. Alternativt kan du brukenpm run build
på hver lagring for å kompilere SCSS og bygge resten av plugin-pakken.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; } }
Her er demoen!
Sjekk det ut - vi har nettopp laget en blokkeringsplugin som henter data og gjengir dem på forsiden av et WordPress-nettsted.
Vi fant et API,
fetch()
-ed data fra den, lagret den i WordPress-databasen, analyserte den og brukte den til noe HTML-oppmerking for å vise på frontend. Ikke verst for en enkelt opplæring, ikke sant?Igjen, vi kan gjøre det samme slik at rangeringene gjengis i Block Editor i tillegg til temaets frontend. Men forhåpentligvis å holde dette fokusert på frontend viser deg hvordan henting av data fungerer i en WordPress-blokk, og hvordan dataene kan struktureres og gjengis for visning.