Der er dukket nogle nye tutorials op her om CSS-Tricks til at arbejde med WordPress-blokke. En af dem er en introduktion til WordPress blokudvikling, og det er et godt sted at lære, hvad blokke er, og at registrere dem i WordPress til brug i sider og indlæg.
Selvom det grundlæggende i blokken er pænt dækket i det indlæg, vil jeg tage det endnu et skridt fremad. Du kan se, i den artikel lærte vi forskellen mellem at gengive blokke i back-end WordPress Block Editor og at gengive dem på front-end-temaet. Eksemplet var en simpel Pullquote Block, der gengav forskelligt indhold og stilarter i hver ende.
Lad os gå videre og se på at bruge dynamisk indhold i en WordPress-blok. Mere specifikt, lad os hente data fra en ekstern API og gengive dem på frontend, når en bestemt blok slippes ind i Block Editor.
Vi skal bygge en blok, der udsender data, der viser fodbold (eh, fodbold) placeringer hentet fra Api-Fodbold.
Der er mere end én måde at integrere en API med en WordPress-blok! Da artiklen om det grundlæggende i blokke allerede har gennemgået processen med at lave en blok fra bunden, vil vi forenkle tingene ved at bruge @wordpress/create-block
pakke til at opstarte vores arbejde og strukturere vores projekt.
Initialiserer vores blok-plugin
Første ting først: lad os oprette et nyt projekt fra kommandolinjen:
npx @wordpress/create-block football-rankings
Jeg ville normalt sparke et projekt som dette i gang ved at lave filerne fra bunden, men kudos til WordPress Core-teamet for dette praktiske værktøj!
Når projektmappen er blevet oprettet af kommandoen, har vi teknisk set en fuldt funktionel WordPress-blok registreret som et plugin. Så lad os gå videre og slippe projektmappen i wp-content/plugins
mappe, hvor du har WordPress installeret (sandsynligvis bedst at arbejde i et lokalt miljø), log derefter ind på WordPress admin og aktiver den fra plugins-skærmen.
Nu hvor vores blok er initialiseret, installeret og aktiveret, gå videre og åbn projektmappen fra kl /wp-content/plugins/football-rankings
. Det vil du gerne cd
der fra kommandolinjen også for at sikre, at vi kan fortsætte udviklingen.
Dette er de eneste filer, vi skal koncentrere os om i øjeblikket:
edit.js
index.js
football-rankings.php
De andre filer i projektet er selvfølgelig vigtige, men er uvæsentlige på dette tidspunkt.
Gennemgang af API-kilden
Vi ved allerede, at vi bruger Api-Fodbold som kommer til os høflighed af RapidAPI. Heldigvis har RapidAPI et dashboard, der automatisk genererer de nødvendige scripts, vi skal bruge for at hente API-dataene til Premier League-stillingen i 2021.
Hvis du vil have et kig på JSON-strukturen, kan du generere visuel repræsentation med JSONCrack.
edit.js
fil
Henter data fra Jeg vil pakke RapidAPI-koden ind i en Reagerer useEffect()
krog med et tomt afhængighedsarray, så det kun kører én gang, når siden er indlæst. På denne måde forhindrer vi WordPress i at kalde API'en, hver gang Block Editor genrenderer. Det kan du tjekke vha wp.data.subscribe()
hvis du gider.
Her er koden, hvor jeg importerer useEffect()
, og derefter vikle den rundt om fetch()
kode, som RapidAPI leverede:
/**
* 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" ) }
);
}
Bemærk, at jeg har forladt return
fungerer stort set intakt, men har inkluderet en note, der bekræfter, at fodboldstillingen er gengivet på forenden. Igen, vi vil kun fokusere på frontend i denne artikel - vi kunne også gengive dataene i Block Editor, men vi overlader det til en anden artikel for at holde tingene fokuseret.
Lagring af API-data i WordPress
Nu hvor vi henter data, skal vi gemme dem et sted i WordPress. Det er her attributes.data
objekt kommer godt med. Vi definerer data.type
som en object
da dataene hentes og formateres som JSON. Sørg for, at du ikke har nogen anden type, ellers vil WordPress ikke gemme dataene, og det giver heller ikke nogen fejl for dig at fejlfinde.
Vi definerer alt dette i vores index.js
fil:
registerBlockType( metadata.name, {
edit: Edit,
attributes: {
data: {
type: "object",
},
},
save,
} );
OK, så WordPress ved nu, at de RapidAPI-data, vi henter, er et objekt. Hvis vi åbner et nyt indlægsudkast i WordPress Block Editor og gemmer indlægget, gemmes dataene nu i databasen. Faktisk, hvis vi kan se det i wp_posts.post_content
felt, hvis vi åbner webstedets database i phpMyAdmin, Sequel Pro, Adminer eller hvilket værktøj du nu bruger.
Udsender JSON-data i frontend
Der er flere måder at udlæse data på frontend. Den måde, jeg vil vise dig, tager de attributter, der er gemt i databasen, og sender dem som en parameter gennem render_callback
funktion i vores football-rankings.php
fil.
Jeg kan godt lide at holde en adskillelse af bekymringer, så hvordan jeg gør dette er at tilføje to nye filer til blok-plugin's build
folder: frontend.js
, frontend.css
(du kan oprette en frontend.scss
fil i src
bibliotek, der kompilerede til CSS i build
vejviser). På denne måde er back-end- og front-end-koderne adskilte og football-rankings.php
filen er lidt nemmere at læse.
/forklaring Med henvisning tilbage til introduktionen til WordPress-blokudvikling er der editor.css
, style.css
filer til back-end og delte stilarter mellem henholdsvis for- og bagenden. Ved at tilføje frontend.scss
(som kompilerer til frontend.css
, Jeg kan isolere stilarter, der kun er beregnet til frontend.
Før vi bekymrer os om de nye filer, her er, hvordan vi kalder dem ind 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();
}Da jeg bruger
render_callback()
metode til attributterne, vil jeg håndtere køen manuelt ligesom Block Editor Handbook foreslår. Det er indeholdt i!is_admin()
condition, og sætter de to filer i kø, så vi undgår at sætte dem i kø, mens vi bruger redigeringsskærmen.Nu hvor vi har to nye filer, vi ringer til, skal vi sørge for, at vi fortæller det
npm
at kompilere dem. Så gør det ipackage.json
Iscripts
sektion:"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 anden måde at inkludere filerne på er at definere dem i blokmetadataene i vores
block.json
fil, som anført i introduktionen til blokudvikling:"viewScript": [ "file:./frontend.js", "example-shared-view-script" ], "style": [ "file:./frontend.css", "example-shared-style" ],
Den eneste grund til at jeg går med
package.json
metode er fordi jeg allerede gør brug afrender_callback()
fremgangsmåde.Gengivelse af JSON-data
I gengivelsesdelen koncentrerer jeg mig kun om en enkelt blok. Generelt vil du gerne målrette mod flere blokke på frontend. I så fald skal du gøre brug af
document.querySelectorAll()
med blokkens specifikke ID.Jeg vil dybest set vente på, at vinduet indlæses og få fat i data for et par nøgleobjekter fra JSON og anvende dem på en markup, der gengiver dem på frontenden. Jeg vil også konvertere
attributes
data til et JSON-objekt, så det er nemmere at læse JavaScript og indstille detaljerne fra JSON til HTML for ting som fodboldligaens logo, holdlogoer og statistik.Kolonnen "Sidste 5 kampe" viser resultatet af et holds seneste fem kampe. Jeg er nødt til manuelt at ændre dataene for det, da API-dataene er i et strengformat. Konvertering af det til et array kan hjælpe med at gøre brug af det i HTML som et separat element for hver af et holds sidste fem kampe.
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 }Hvad styling angår, er du fri til at gøre, hvad du vil! Hvis du vil have noget at arbejde med, har jeg et komplet sæt stilarter, du kan bruge som udgangspunkt.
Jeg stylede ting i SCSS siden
@wordpress/create-block
pakken understøtter det ud af æsken. Løbnpm run start
i kommandolinjen for at se SCSS-filerne og kompilere dem til CSS ved gem. Alternativt kan du brugenpm run build
på hver lagring for at kompilere SCSS'en og bygge resten af 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!
Tjek det ud - vi har lige lavet et blok-plugin, der henter data og gengiver det på forsiden af et WordPress-websted.
Vi fandt en API,
fetch()
-eded data fra det, gemte det i WordPress-databasen, parsede det og anvendte det til noget HTML-markup for at blive vist på frontend. Ikke dårligt for en enkelt tutorial, vel?Igen kan vi gøre den samme slags ting, så placeringerne gengives i Block Editor ud over temaets frontend. Men forhåbentlig viser det at holde dette fokuseret på frontend, hvordan hentning af data fungerer i en WordPress-blok, og hvordan dataene kan struktureres og gengives til visning.