Ini adalah lanjutan dari artikel saya yang lalu tentang “Merendering Data API Eksternal di Blok WordPress di Front End”. Di bagian terakhir itu, kami belajar cara mengambil API eksternal dan mengintegrasikannya dengan blok yang merender data yang diambil di bagian depan situs WordPress.
Masalahnya, kami menyelesaikan ini dengan cara yang mencegah kami melihat data di Editor Blok WordPress. Dengan kata lain, kita dapat menyisipkan blok pada halaman tetapi kita tidak mendapatkan pratinjaunya. Kami hanya bisa melihat blok ketika itu diterbitkan.
Mari kita lihat kembali contoh plugin blok yang kita buat di artikel sebelumnya. Hanya saja kali ini, kita akan menggunakan JavaScript dan ekosistem React WordPress untuk mengambil dan merender data tersebut di Editor Blok back-end juga.
Di mana kami tinggalkan
Saat kita memulai ini, ini demonya di mana kami mendarat di artikel terakhir yang dapat Anda referensikan. Anda mungkin telah memperhatikan bahwa saya menggunakan render_callback
metode di artikel terakhir sehingga saya dapat menggunakan atribut dalam file PHP dan merender konten.
Nah, itu mungkin berguna dalam situasi di mana Anda mungkin harus menggunakan beberapa fungsi WordPress atau PHP asli untuk membuat blok dinamis. Tetapi jika Anda hanya ingin menggunakan ekosistem JavaScript dan React (JSX, khususnya) WordPress untuk merender HTML statis bersama dengan atribut yang disimpan dalam database, Anda hanya perlu fokus pada Edit
dan Save
fungsi plugin blok.
- Grafik
Edit
fungsi membuat konten berdasarkan apa yang ingin Anda lihat di Editor Blok. Anda dapat memiliki komponen React interaktif di sini. - Grafik
Save
fungsi membuat konten berdasarkan apa yang ingin Anda lihat di ujung depan. Anda tidak dapat memiliki komponen React biasa atau hook di sini. Ini digunakan untuk mengembalikan HTML statis yang disimpan ke database Anda bersama dengan atributnya.
Grafik Save
fungsinya adalah tempat kita nongkrong hari ini. Kita dapat membuat komponen interaktif di front-end, tetapi untuk itu kita perlu memasukkan dan mengaksesnya secara manual di luar Save
berfungsi dalam file seperti yang kami lakukan di artikel terakhir.
Jadi, saya akan membahas dasar yang sama yang kami lakukan di artikel terakhir, tetapi kali ini Anda dapat melihat pratinjau di Editor Blok sebelum Anda mempublikasikannya ke ujung depan.
Alat peraga blok
Saya sengaja meninggalkan penjelasan apa pun tentang edit
props function di artikel terakhir karena itu akan mengalihkan fokus dari poin utama, rendering.
Jika Anda berasal dari latar belakang React, Anda mungkin akan mengerti apa yang saya bicarakan, tetapi jika Anda baru dalam hal ini, saya akan merekomendasikan memeriksa komponen dan props dalam dokumentasi React.
Jika kita mencatat props
objek ke konsol, ia mengembalikan daftar fungsi dan variabel WordPress yang terkait dengan blok kami:
Kami hanya membutuhkan attributes
objek dan setAttributes
fungsi yang akan saya rusak dari props
objek dalam kode saya. Pada artikel terakhir, saya telah memodifikasi kode RapidAPI sehingga saya dapat menyimpan data API melalui setAttributes()
. Alat peraga hanya dapat dibaca, jadi kami tidak dapat mengubahnya secara langsung.
Alat peraga blok mirip dengan variabel status dan setState
di React, tetapi React bekerja di sisi klien dan setAttributes()
digunakan untuk menyimpan atribut secara permanen di database WordPress setelah menyimpan posting. Jadi, yang perlu kita lakukan adalah menyelamatkan mereka ke attributes.data
dan kemudian menyebutnya sebagai nilai awal untuk useState()
variabel.
edit
fungsi
Grafik Saya akan menyalin-tempel kode HTML yang kami gunakan football-rankings.php
di artikel terakhir dan edit sedikit untuk beralih ke latar belakang JavaScript. Ingat bagaimana kami membuat dua file tambahan di artikel terakhir untuk gaya dan skrip ujung depan? Dengan cara kita mendekati hal-hal hari ini, tidak perlu membuat file-file itu. Sebagai gantinya, kita bisa memindahkan semuanya ke Edit
fungsi.
Kode lengkap
import { useState } from "@wordpress/element";
export default function Edit(props) {
const { attributes, setAttributes } = props;
const [apiData, setApiData] = useState(null);
function fetchData() {
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 }; // Deep clone the response data
setAttributes({ data: newData }); // Store the data in WordPress attributes
setApiData(newData); // Modify the state with the new data
})
.catch((err) => console.error(err));
}
return (
{apiData && (
Rank
Logo
Team name
GP
GW
GD
GL
GF
GA
Pts
Form history
{/* Usage of [0] might be weird but that is how the API structure is. */}
{apiData.response[0].league.standings[0].map((el) => {
{/* Destructure the required data from all */}
const { played, win, draw, lose, goals } = el.all;
return (
{el.rank}
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => {
return (
{result}
);
})}
);
}
)}
)}
);
}
Saya telah menyertakan kait React useState()
dari @wordpress/element
daripada menggunakannya dari perpustakaan Bereaksi. Itu karena jika saya memuat dengan cara biasa, itu akan mengunduh React untuk setiap blok yang saya gunakan. Tetapi jika saya menggunakan @wordpress/element
itu memuat dari satu sumber, yaitu, lapisan WordPress di atas React.
Kali ini, saya juga belum membungkus kode di dalamnya useEffect()
tetapi di dalam fungsi yang dipanggil hanya saat mengklik tombol sehingga kami memiliki pratinjau langsung dari data yang diambil. Saya telah menggunakan variabel status yang disebut apiData
untuk membuat tabel liga bersyarat. Jadi, setelah tombol diklik dan data diambil, saya mengatur apiData
ke data baru di dalam fetchData()
dan ada rendering dengan HTML tabel peringkat sepak bola yang tersedia.
Anda akan melihat bahwa setelah posting disimpan dan halaman di-refresh, tabel liga hilang. Itu karena kita menggunakan keadaan kosong (null
) Untuk apiData
nilai awal . Saat pos disimpan, atribut disimpan ke attributes.data
objek dan kami menyebutnya sebagai nilai awal untuk useState()
variabel seperti ini:
const [apiData, setApiData] = useState(attributes.data);
save
fungsi
Grafik Kami akan melakukan hal yang hampir sama persis dengan save
fungsi, tetapi memodifikasinya sedikit. Misalnya, tidak perlu tombol "Ambil data" di ujung depan, dan tombol apiData
variabel status juga tidak diperlukan karena kami sudah memeriksanya di edit
fungsi. Tapi kita butuh random apiData
variabel yang memeriksa attributes.data
untuk merender BEJ secara kondisional atau jika tidak, itu akan menimbulkan kesalahan yang tidak ditentukan dan UI Editor Blok akan menjadi kosong.
Kode lengkap
export default function save(props) {
const { attributes, setAttributes } = props;
let apiData = attributes.data;
return (
{/* Only render if apiData is available */}
{apiData && (
Rank
Logo
Team name
GP
GW
GD
GL
GF
GA
Pts
Form history
{/* Usage of [0] might be weird but that is how the API structure is. */}
{apiData.response[0].league.standings[0].map((el) => {
const { played, win, draw, lose, goals } = el.all;
return (
{el.rank}
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => {
return (
{result}
);
})}
);
})}
)}
);
}
Jika Anda memodifikasi save
fungsi setelah blok sudah ada di Editor Blok, itu akan menunjukkan kesalahan seperti ini:
Itu karena markup di konten yang disimpan berbeda dari markup di baru kami save
fungsi. Karena kita berada dalam mode pengembangan, lebih mudah untuk menghapus bock dari halaman saat ini dan memasukkannya kembali sebagai blok baru — dengan begitu, kode yang diperbarui digunakan sebagai gantinya dan semuanya kembali sinkron.
Situasi menghapus dan menambahkannya lagi dapat dihindari jika kita telah menggunakan render_callback
metode karena outputnya dinamis dan dikendalikan oleh PHP alih-alih fungsi simpan. Jadi setiap metode memiliki kelebihan dan kekurangannya masing-masing.
Tom Nowell memberikan penjelasan menyeluruh tentang apa yang tidak boleh dilakukan di a save
fungsi di Stack Overflow ini menjawab.
Menata blok di editor dan ujung depan
Mengenai gaya, itu akan menjadi hal yang hampir sama dengan yang kita lihat di artikel terakhir, tetapi dengan beberapa perubahan kecil yang telah saya jelaskan di komentar. Saya hanya memberikan gaya lengkap di sini karena ini hanya bukti konsep daripada sesuatu yang ingin Anda salin-tempel (kecuali jika Anda benar-benar membutuhkan blok untuk menampilkan peringkat sepak bola yang ditata seperti ini). Dan perhatikan bahwa saya masih menggunakan SCSS yang dikompilasi ke CSS di build.
Gaya editor
/* Target all the blocks with the data-title="Football Rankings" */
.block-editor-block-list__layout
.block-editor-block-list__block.wp-block[data-title="Football Rankings"] {
/* By default, the blocks are constrained within 650px max-width plus other design specific code */
max-width: unset;
background: linear-gradient(to right, #8f94fb, #4e54c8);
display: grid;
place-items: center;
padding: 60px 0;
/* Button CSS - From: https://getcssscan.com/css-buttons-examples - Some properties really not needed :) */
button.fetch-data {
align-items: center;
background-color: #ffffff;
border: 1px solid rgb(0 0 0 / 0.1);
border-radius: 0.25rem;
box-shadow: rgb(0 0 0 / 0.02) 0 1px 3px 0;
box-sizing: border-box;
color: rgb(0 0 0 / 0.85);
cursor: pointer;
display: inline-flex;
font-family: system-ui, -apple-system, system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 16px;
font-weight: 600;
justify-content: center;
line-height: 1.25;
margin: 0;
min-height: 3rem;
padding: calc(0.875rem - 1px) calc(1.5rem - 1px);
position: relative;
text-decoration: none;
transition: all 250ms;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
vertical-align: baseline;
width: auto;
&:hover,
&:focus {
border-color: rgb(0, 0, 0, 0.15);
box-shadow: rgb(0 0 0 / 0.1) 0 4px 12px;
color: rgb(0, 0, 0, 0.65);
}
&:hover {
transform: translateY(-1px);
}
&:active {
background-color: #f0f0f1;
border-color: rgb(0 0 0 / 0.15);
box-shadow: rgb(0 0 0 / 0.06) 0 2px 4px;
color: rgb(0 0 0 / 0.65);
transform: translateY(0);
}
}
}
Gaya ujung depan
/* Front-end block styles */
.wp-block-post-content .wp-block-football-rankings-league-table {
background: linear-gradient(to right, #8f94fb, #4e54c8);
max-width: unset;
display: grid;
place-items: center;
}
#league-standings {
width: 900px;
margin: 60px 0;
max-width: unset;
font-size: 16px;
.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-color: transparent;
background-repeat: no-repeat;
background-size: contain;
background-position: right;
.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;
top: 3px;
position: relative;
}
.stats {
display: flex;
gap: 15px;
& > div {
width: 30px;
text-align: center;
}
}
.last-5-games {
display: flex;
gap: 5px;
& > div {
width: 25px;
height: 25px;
text-align: center;
border-radius: 3px;
font-size: 15px;
& .result-W {
background: #347d39;
color: white;
}
& .result-D {
background: gray;
color: white;
}
& .result-L {
background: lightcoral;
color: white;
}
}
}
Kami menambahkan ini ke src/style.scss
yang menangani penataan gaya di editor dan frontend. Saya tidak akan dapat membagikan URL demo karena memerlukan akses editor tetapi saya memiliki video yang direkam untuk Anda lihat demonya:
Cukup rapi, bukan? Sekarang kita memiliki blok yang berfungsi penuh yang tidak hanya merender di front end, tetapi juga mengambil data API dan merender di sana di Editor Blok — dengan tombol segarkan untuk boot!
Tetapi jika kita ingin mengambil penuh keuntungan dari Editor Blok WordPress, kita harus mempertimbangkan untuk memetakan beberapa elemen UI blok untuk kontrol blok untuk hal-hal seperti pengaturan warna, tipografi, dan spasi. Itu langkah selanjutnya yang bagus dalam perjalanan pembelajaran pengembangan blok.