Pojawiło się kilka nowych samouczków na temat sztuczek CSS dotyczących pracy z blokami WordPress. Jeden z nich to wprowadzenie do tworzenia bloków WordPress i jest to dobre miejsce, aby dowiedzieć się, czym są bloki i zarejestrować je w WordPressie do użytku na stronach i postach.
Chociaż podstawy bloków są ładnie omówione w tym poście, chcę zrobić kolejny krok do przodu. Widzisz, w tym artykule poznaliśmy różnicę między renderowaniem bloków w edytorze bloków WordPress zaplecza a renderowaniem ich w motywie frontonu. Przykładem był prosty blok Pullquote, który renderował różne treści i style na każdym końcu.
Pójdźmy dalej i spójrzmy na używanie zawartość dynamiczna w bloku WordPress. Mówiąc dokładniej, pobierzmy dane z zewnętrznego interfejsu API i wyrenderujmy je w interfejsie użytkownika, gdy określony blok zostanie upuszczony do Edytora bloków.
Zbudujemy blok, który będzie wyświetlał dane pokazujące piłkę nożną (er, piłka nożna) rankingi wyciągnięte z Api-piłka nożna.
Istnieje więcej niż jeden sposób na zintegrowanie API z blokiem WordPress! Ponieważ artykuł o podstawach bloków przeszedł już przez proces tworzenia bloku od podstaw, zamierzamy uprościć rzeczy, używając @wordpress/create-block
pakiet do rozruchu naszej pracy i struktury naszego projektu.
Inicjowanie naszej wtyczki blokującej
Po pierwsze: uruchommy nowy projekt z wiersza poleceń:
npx @wordpress/create-block football-rankings
Normalnie wykopałbym taki projekt, tworząc pliki od zera, ale chwała dla zespołu WordPress Core za to przydatne narzędzie!
Po utworzeniu folderu projektu za pomocą polecenia, technicznie mamy w pełni funkcjonalny blok WordPress zarejestrowany jako wtyczka. Więc chodźmy dalej i wrzućmy folder projektu do wp-content/plugins
katalogu, w którym masz zainstalowany WordPress (najlepiej pracować w środowisku lokalnym), a następnie zaloguj się do administratora WordPressa i aktywuj go z ekranu Wtyczki.
Teraz, gdy nasz blok jest zainicjowany, zainstalowany i aktywowany, otwórz folder projektu z at /wp-content/plugins/football-rankings
. Będziesz chciał cd
tam również z wiersza poleceń, aby upewnić się, że możemy kontynuować rozwój.
To jedyne pliki, na których musimy się w tej chwili skoncentrować:
edit.js
index.js
football-rankings.php
Inne pliki w projekcie są oczywiście ważne, ale w tym momencie są nieistotne.
Przeglądanie źródła API
Już wiemy, że używamy Api-piłka nożna który przychodzi do nas dzięki uprzejmości RapidAPI. Na szczęście RapidAPI ma pulpit nawigacyjny, który automatycznie generuje wymagane skrypty potrzebne do pobrania danych API dla tabeli Premier League 2021.
Jeśli chcesz spojrzeć na strukturę JSON, możesz wygenerować wizualną reprezentację za pomocą JSONCrack.
edit.js
filet
Pobieranie danych z Zamierzam zawinąć kod RapidAPI w React useEffect()
hak z pustą tablicą zależności, aby działała tylko raz, gdy strona jest ładowana. W ten sposób uniemożliwiamy WordPressowi wywoływanie interfejsu API za każdym razem, gdy Edytor bloku jest ponownie renderowany. Możesz to sprawdzić za pomocą wp.data.subscribe()
jeśli chcesz.
Oto kod, do którego importuję useEffect()
, a następnie owinąć wokół fetch()
kod dostarczony przez 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" ) }
);
}
Zauważ, że zostawiłem return
działają prawie nienaruszone, ale zawierają notatkę, która potwierdza, że tabele piłkarskie są renderowane na froncie. Ponownie, skupimy się tylko na interfejsie w tym artykule — moglibyśmy również renderować dane w Edytorze bloku, ale zostawimy to na inny artykuł, aby zachować koncentrację.
Przechowywanie danych API w WordPress
Teraz, gdy pobieramy dane, musimy je przechowywać gdzieś w WordPressie. To tutaj attributes.data
obiekt przydaje się. Definiujemy data.type
jako object
ponieważ dane są pobierane i formatowane w formacie JSON. Upewnij się, że nie masz żadnego innego typu, w przeciwnym razie WordPress nie zapisze danych ani nie wygeneruje żadnego błędu podczas debugowania.
Wszystko to definiujemy w naszym index.js
file:
registerBlockType( metadata.name, {
edit: Edit,
attributes: {
data: {
type: "object",
},
},
save,
} );
OK, więc WordPress wie, że pobierane przez nas dane RapidAPI to obiekt. Jeśli otworzymy nową wersję roboczą posta w edytorze bloków WordPress i zapiszemy post, dane są teraz przechowywane w bazie danych. W rzeczywistości, jeśli możemy to zobaczyć w wp_posts.post_content
pole, jeśli otworzymy bazę danych witryny w phpMyAdmin, Sequel Pro, Adminer lub jakimkolwiek innym narzędziu, którego używasz.
Wyprowadzanie danych JSON w interfejsie użytkownika
Istnieje wiele sposobów wyprowadzania danych w interfejsie użytkownika. Sposób, który ci pokażę, polega na tym, że atrybuty przechowywane w bazie danych są przekazywane jako parametr przez render_callback
funkcjonować w naszym football-rankings.php
plik.
Lubię zachować separację obaw, więc jak to zrobić, to dodać dwa nowe pliki do wtyczki bloku build
folder: frontend.js
i frontend.css
(możesz stworzyć frontend.scss
Plik w src
katalog, który skompilowano do CSS w build
informator). W ten sposób kody back-end i front-end są oddzielne, a football-rankings.php
plik jest trochę łatwiejszy do odczytania.
/explanation Nawiązując do wstępu do tworzenia bloków WordPress, są editor.css
i style.css
pliki dla stylów zaplecza i współdzielonego odpowiednio między frontonem i backendem. Poprzez dodanie frontend.scss
(który kompiluje się do frontend.css
, mogę wyizolować style, które są przeznaczone tylko dla frontonu.
Zanim zaczniemy się martwić o te nowe pliki, oto jak je nazywamy 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();
}Ponieważ używam
render_callback()
metody dla atrybutów, będę obsługiwał kolejkę ręcznie, tak jak Podręcznik edytora bloków sugeruje. To jest zawarte w!is_admin()
warunku i umieszcza w kolejce dwa pliki, aby uniknąć umieszczania ich w kolejce podczas korzystania z ekranu edytora.Teraz, gdy mamy dwa nowe pliki, do których dzwonimy, musimy się upewnić, że mówimy
npm
aby je skompilować. Więc zrób to wpackage.json
, Wscripts
sekcja:"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" },
Innym sposobem włączenia plików jest zdefiniowanie ich w metadanych bloku zawartych w naszym
block.json
file, jak wspomniano we wstępie do tworzenia bloków:"viewScript": [ "file:./frontend.js", "example-shared-view-script" ], "style": [ "file:./frontend.css", "example-shared-style" ],
Jedyny powód, dla którego idę z
package.json
metoda polega na tym, że już korzystam zrender_callback()
Metoda.Renderowanie danych JSON
W części renderowania koncentruję się tylko na jednym bloku. Ogólnie rzecz biorąc, chciałbyś celować w wiele bloków z przodu. W takim przypadku musisz skorzystać z
document.querySelectorAll()
z konkretnym identyfikatorem bloku.Zasadniczo zamierzam poczekać, aż okno załaduje i pobierze dane dla kilku kluczowych obiektów z JSON i zastosuje je do niektórych znaczników, które renderują je na interfejsie użytkownika. Zamierzam też przekonwertować
attributes
dane do obiektu JSON, aby łatwiej było czytać za pomocą JavaScript i ustawić szczegóły z JSON na HTML dla takich rzeczy, jak logo ligi piłkarskiej, logo zespołu i statystyki.Kolumna „Ostatnie 5 meczów” pokazuje wyniki ostatnich pięciu meczów drużyny. Muszę ręcznie zmienić dane, ponieważ dane API są w formacie ciągu. Przekształcenie go w tablicę może pomóc w wykorzystaniu go w HTML jako oddzielnego elementu dla każdego z ostatnich pięciu meczów drużyny.
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 }Jeśli chodzi o stylizację, możesz robić, co chcesz! Jeśli chcesz coś z czym pracować, mam pełny zestaw stylów, których możesz użyć jako punktu wyjścia.
Stylizowałem rzeczy w SCSS od
@wordpress/create-block
pakiet obsługuje go po wyjęciu z pudełka. Biegaćnpm run start
w wierszu poleceń, aby obejrzeć pliki SCSS i skompilować je do CSS przy zapisywaniu. Alternatywnie możesz użyćnpm run build
przy każdym zapisie, aby skompilować SCSS i zbudować resztę pakietu wtyczek.Zobacz 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; } }
Oto demo!
Sprawdź to — właśnie stworzyliśmy wtyczkę blokową, która pobiera dane i renderuje je na interfejsie witryny WordPress.
Znaleźliśmy API,
fetch()
-ed z niego dane, zapisał je w bazie danych WordPressa, przeanalizował i zastosował do niektórych znaczników HTML, aby wyświetlić je w interfejsie użytkownika. Nieźle jak na jeden samouczek, prawda?Ponownie, możemy zrobić to samo, aby oprócz interfejsu motywu renderować rankingi w Edytorze bloku. Ale miejmy nadzieję, że skupienie się na interfejsie użytkownika pokazuje, jak działa pobieranie danych w bloku WordPress oraz jak dane mogą być ustrukturyzowane i renderowane do wyświetlania.