تا اینجا نحوه کار با داده های یک API خارجی در یک بلوک سفارشی وردپرس را توضیح داده ایم. ما روند را طی کردیم واکشی آن داده برای استفاده در قسمت جلویی یک سایت وردپرسی و نحوه انجام آن آن را مستقیماً در ویرایشگر بلاک وردپرس ارائه دهید هنگام قرار دادن بلوک در محتوا. این بار، ما قصد داریم این دو مقاله را با اتصال به کنترل پنل ویرایشگر بلوک برای ایجاد یک رابط کاربری تنظیمات برای بلوکی که ساختهایم، پل بزنیم.
کار با API های خارجی در بلوک های وردپرس
شما کنترل پنل مورد نظر من را می شناسید، درست است؟ این همان پانل در سمت راست است که شامل تنظیمات پست و بلوک در ویرایشگر بلوک است.
آن ناحیه برجسته قرمز را می بینید؟ اونم کنترل پنل یک بلوک پاراگراف در حال حاضر انتخاب شده است و تنظیمات مربوط به آن در پانل نمایش داده می شود. ما می توانیم سبک، رنگ، تایپوگرافی ... تعدادی چیز را تغییر دهیم!
خوب، این دقیقاً همان کاری است که ما این بار انجام می دهیم. ما میخواهیم کنترلهایی را برای تنظیمات بلوک رتبهبندی فوتبال که در دو مقاله گذشته روی آن کار کردیم ایجاد کنیم. آخرین بار، دکمهای در بلوک خود ایجاد کردیم که دادههای خارجی را برای رتبهبندی فوتبال واکشی میکند. ما قبلاً URL و نقاط پایانی مورد نیاز خود را می دانستیم. اما اگر بخواهیم رتبه ای را برای کشور دیگری کسب کنیم چه؟ یا شاید لیگ دیگری؟ در مورد داده های یک فصل مختلف چطور؟
برای انجام این کار به کنترل های فرم نیاز داریم. ما میتوانیم از مؤلفههای تعاملی React استفاده کنیم - مانند React-Select - برای مرور گزینه های مختلف API که برای تجزیه آن داده ها در دسترس هستند. اما نیازی به آن نیست زیرا وردپرس با مجموعهای از اجزای اصلی عرضه میشود که ما مستقیماً به آنها متصل میشویم!
La مستندات برای این اجزا - نامیده می شود InspectorControls
- در حال بهتر شدن است راهنمای ویرایشگر بلاک وردپرس. این با گذشت زمان حتی بهتر می شود، اما در عین حال، ما نیز آن را داریم کتاب داستان گوتنبرگ وردپرس و اجزای گوتنبرگ وردپرس سایت هایی برای کمک بیشتر
معماری API
قبل از اینکه وارد هر چیزی شویم، ایده خوبی است که در وهله اول نقشه مورد نیاز خود را مشخص کنیم. من ساختار داده های RapidAPI را که در حال واکشی هستیم ترسیم کرده ام تا بدانیم چه چیزی در دسترس ما است:
فصل ها و کشورها دو نقطه پایانی سطح بالایی هستند که به نقطه پایانی لیگ نگاشت می شوند. از آنجا، ما بقیه دادههایی را داریم که از قبل برای پر کردن جدول رتبهبندی استفاده میکنیم. بنابراین، کاری که میخواهیم انجام دهیم این است که تنظیماتی را در ویرایشگر بلاک وردپرس ایجاد کنیم که دادهها را بر اساس فصل، کشور و لیگ فیلتر کند، سپس آن دادههای فیلتر شده را به جدول رتبهبندی منتقل کند. این به ما این امکان را می دهد که بلوک را در هر صفحه یا پست وردپرس رها کنیم و تغییرات داده ها را در بلوک نمایش دهیم.
برای اینکه بتوانیم در جدول رده بندی قرار بگیریم، ابتدا باید لیگ ها را بدست آوریم. و برای بدست آوردن لیگ ها، ابتدا باید کشورها و/یا فصل ها را بدست آوریم. می توانید نقاط پایانی مختلف را در داشبورد RapidAPI مشاهده کنید.
ترکیبهای مختلفی از دادهها وجود دارد که میتوانیم از آنها برای تکمیل رتبهبندی استفاده کنیم، و ممکن است شما ترجیح دهید کدام داده را میخواهید. به خاطر این مقاله، میخواهیم گزینههای زیر را در پنل تنظیمات بلوک ایجاد کنیم:
- کشور را انتخاب کن
- لیگ را انتخاب کنید
- فصل را انتخاب کنید
سپس دکمه ای برای ارسال آن انتخاب ها و واکشی داده های مربوطه و ارسال آنها به جدول رتبه بندی خواهیم داشت.
فهرستی از کشورها را بارگیری و ذخیره کنید
اگر فهرستی از کشورها برای انتخاب نداشته باشیم، نمیتوانیم کشور مورد نظر خود را انتخاب کنیم. بنابراین، اولین وظیفه ما گرفتن لیستی از کشورها از RapidAPI است.
ایده آل ترین چیز این است که لیست کشورها را زمانی که بلوک در صفحه یا محتوای پست استفاده می شود، دریافت کنید. اگر بلوک مورد استفاده قرار نگیرد، نیازی به واکشی چیزی نیست. رویکرد بسیار شبیه به کاری است که در آن انجام دادیم مقاله اول، تفاوت در این است که ما از یک نقطه پایانی API متفاوت و ویژگی های مختلف برای ذخیره لیست کشورهای برگشتی استفاده می کنیم. راههای دیگری برای واکشی دادهها در وردپرس وجود دارد، مانند api-fetch، اما این خارج از محدوده کاری است که ما در اینجا انجام می دهیم.
میتوانیم فهرست کشورها را پس از کپی کردن از دادههای API به صورت دستی اضافه کنیم، یا میتوانیم از یک API یا کتابخانه جداگانه برای پر کردن کشورها استفاده کنیم. اما API مورد استفاده ما از قبل فهرستی از کشورها دارد، بنابراین من فقط از یکی از نقاط پایانی آن استفاده می کنم. بیایید مطمئن شویم زمانی که بلوک در صفحه یا محتوای پست در ویرایشگر بلوک درج میشود، فهرست اولیه کشور بارگیری میشود:
// edit.js
const [countriesList, setCountriesList] = useState(null);
useEffect(() => {
let countryOptions = {
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/countries", countryOptions)
.then( (response) => response.json() )
.then( (response) => {
let countriesArray = { ...response };
console.log("Countries list", countriesArray.response);
setCountriesList(countriesArray.response);
})
.catch((err) => console.error(err));
}, []);
ما یک متغیر حالت برای ذخیره لیست کشورها داریم. در مرحله بعد، ما می خواهیم یک کامپوننت را از آن وارد کنیم @wordpress/block-editor بسته به نام InspectorControls
جایی که تمام اجزایی که برای ایجاد کنترل های تنظیمات خود نیاز داریم قرار دارند.
import { InspectorControls } from "@wordpress/block-editor";
مال بسته GitHub repo خوب توضیح میده InspectorControls
. در مثال ما، میتوانیم از آن برای کنترل تنظیمات دادههای API مانند Country، League و Season استفاده کنیم. در اینجا یک پیش نمایش وجود دارد تا شما ایده ای از رابط کاربری که در حال ساخت آن هستیم داشته باشید:
و هنگامی که آن انتخاب ها در تنظیمات بلوک انجام شد، از آنها استفاده می کنیم بلوک Edit
تابع:
{ countriesList && (
)}
در اینجا، من مطمئن می شوم که از رندر شرطی استفاده می کنیم تا تابع فقط مؤلفه را بارگیری کند بعد از لیست کشورها بارگذاری شده است. اگر در مورد آن تعجب می کنید LeagueSettings
کامپوننت، یک جزء سفارشی است که من در یک کامپوننت جداگانه ایجاد کردم components
زیر پوشه در بلوک تا بتوانیم یک پوشه تمیزتر و سازماندهی شده داشته باشیم Edit
به جای صدها خط داده کشوری که باید در یک فایل به آن پرداخته شود.
ما می توانیم آن را وارد کنیم edit.js
پرونده مانند این:
import { LeagueSettings } from "./components/LeagueSettings";
در مرحله بعد، ما در حال ارسال لوازم مورد نیاز به LeagueSettings
جزء از والدین Edit
کامپوننت تا بتوانیم به متغیرهای حالت و ویژگی ها از روی دسترسی داشته باشیم LeagueSettings
جزء فرزند ما همچنین می توانیم این کار را با روش های دیگری مانند Context API برای جلوگیری از حفاری پایه، اما آنچه در حال حاضر داریم برای کاری که انجام می دهیم کاملاً مناسب است.
بخش های دیگر از Edit
تابع همچنین می تواند به اجزاء تبدیل شود. به عنوان مثال، کد جدول رده بندی لیگ را می توان در یک جزء جداگانه قرار داد - مانند شاید LeagueTable.js
- و سپس همان طور که ما وارد کردیم وارد شد LeagueSettings
به Edit
تابع.
LeagueSettings.js
پرونده
در داخل LeagueSettings
درست مثل دیگری است واکنش دهنده که از طریق آن میتوانیم پایههای مولفه والد را تخریب کنیم. من قصد دارم از سه متغیر حالت و یک متغیر اضافی استفاده کنم leagueID
State زیرا می خواهیم شناسه را از آن استخراج کنیم league
هدف - شی:
const [country, setCountry] = useState(null);
const [league, setLeague] = useState(null);
const [season, setSeason] = useState(null);
const [leagueID, setLeagueID] = useState(null);
اولین کاری که می خواهیم انجام دهیم این است که آن را وارد کنیم PanelBody
جزء از بسته @wordpress/block-editor:
import { PanelBody } from "@wordpress/block-editor";
... و آن را در ما قرار دهید return
عملکرد:
وجود دارد سایر برچسب ها و ویژگی های پانل - استفاده از اینها فقط ترجیح شخصی من است. هیچ یک از بقیه مورد نیاز نیست ... اما به همه اجزا نگاه کنید ما برای ایجاد یک پنل تنظیمات در دسترس داریم! من سادگی را دوست دارم PanelBody
برای مورد استفاده ما گسترش می یابد و جمع می شود تا تنظیمات کرکره ای برای بلوک آشکار شود و تمام.
صحبت از آن، ما یک انتخاب برای آن انتخاب داریم. ما می توانستیم استفاده کنیم SelectControl
جزء یا الف ComboBoxControl
، که اسناد آن را به عنوان "نسخه بهبود یافته a SelectControl
، با اضافه شدن امکان جستجوی گزینه ها با استفاده از ورودی جستجو." این برای ما خوب است زیرا لیست کشورها می تواند بسیار طولانی شود و کاربران می توانند یک جستجوی جستجو انجام دهند یا از یک لیست انتخاب کنند.
در اینجا یک مثال از چگونگی یک ComboboxControl
می تواند برای لیست کشور ما کار کند:
handleCountryChange(value) }
onInputChange={ (inputValue) => {
setFilteredCountryOptions(
setupCountrySelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase())
)
);
}}
/>
La ComboboxControl
قابل تنظیم است به این معنا که می توانیم اندازه های مختلف را برای برچسب و مقادیر کنترل اعمال کنیم:
{
value: 'small',
label: 'Small',
},
اما دادههای API ما در این نحو نیست، بنابراین میتوانیم آن را تبدیل کنیم countriesList
آرایه ای که از مولفه والد می آید وقتی بلوک گنجانده شود:
let setupCountrySelect;
setupCountrySelect = countriesList.map((country) => {
return {
label: country.name,
value: country.name,
};
});
زمانی که کشوری از ComboboxControl
، مقدار کشور تغییر می کند و ما داده ها را بر این اساس فیلتر می کنیم:
function handleCountryChange(value) {
// Set state of the country
setCountry(value);
// League code from RapidAPI
const options = {
method: "GET",
headers: {
"X-RapidAPI-Key": "Your RapidAPI key",
"X-RapidAPI-Host": "api-football-v1.p.rapidapi.com",
},
};
fetch(`https://api-football-v1.p.rapidapi.com/v3/leagues?country=${value}`, options)
.then((response) => response.json())
.then((response) => {
return response.response;
})
.then((leagueOptions) => {
// Set state of the league variable
setLeague(leagueOptions);
// Convert it as we did for Country options
setupLeagueSelect = leagueOptions.map((league) => {
return {
label: league.league.name,
value: league.league.name,
};
});
setFilteredLeagueOptions(setupLeagueSelect);
})
.catch((err) => console.error(err));
}
توجه داشته باشید که من از سه متغیر حالت دیگر برای مدیریت تغییرات هنگام تغییر انتخاب کشور استفاده می کنم:
const [filteredCountryOptions, setFilteredCountryOptions] = useState(setupCountrySelect);
const [filteredLeagueOptions, setFilteredLeagueOptions] = useState(null);
const [filteredSeasonOptions, setFilteredSeasonOptions] = useState(null);
در مورد سایر گزینه های تنظیمات چطور؟
من کدی را که برای تنظیمات دیگر استفاده کردم نشان خواهم داد، اما تنها کاری که انجام می دهد این است که هنگام تعریف خطاها برای موارد خاص، موارد عادی را در نظر بگیرد. به عنوان مثال، خطاهایی در برخی کشورها و لیگ ها وجود دارد زیرا:
- هیچ رتبه بندی برای برخی لیگ ها وجود ندارد، و
- برخی از لیگ ها جدول رده بندی دارند اما در یک جدول قرار ندارند.
این یک آموزش جاوا اسکریپت یا React نیست، بنابراین به شما اجازه میدهم موارد خاص API را که قصد استفاده از آن را دارید، مدیریت کنید:
function handleLeagueChange(value) {
setLeague(value);
if (league) {
const selectedLeague = league.filter((el) => {
if (el.league.name === value) {
return el;
}
});
if (selectedLeague) {
setLeague(selectedLeague[0].league.name);
setLeagueID(selectedLeague[0].league.id);
setupSeasonSelect = selectedLeague[0].seasons.map((season) => {
return {
label: season.year,
value: season.year,
};
});
setFilteredSeasonOptions(setupSeasonSelect);
}
} else {
return;
}
}
function handleSeasonChange(value) {
setSeason(value);
}
ارسال تنظیمات تنظیمات
در آخرین مقاله، ما یک دکمه در ویرایشگر بلوک ایجاد کردیم که داده های تازه را از API واکشی می کند. اکنون که تنظیمات داریم دیگر نیازی به آن نیست. خوب، ما به آن نیاز داریم - نه در جایی که در حال حاضر است. به جای اینکه مستقیماً آن را در بلوکی که در ویرایشگر بلوک رندر شده است داشته باشیم، آن را به ما منتقل می کنیم. PanelBody
جزء برای ارسال انتخاب های تنظیمات.
بنابراین، دوباره به داخل LeagueSettings.js
:
// When countriesList is loaded, show the country combo box
{ countriesList && (
handleCountryChange(value)}
onInputChange={(inputValue) => {
setFilteredCountryOptions(
setupCountrySelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase())
)
);
}}
/>
)}
// When filteredLeagueOptions is set through handleCountryChange, show league combobox
{ filteredLeagueOptions && (
handleLeagueChange(value)}
onInputChange={(inputValue) => {
setFilteredLeagueOptions(
setupLeagueSelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase())
)
);
}}
/>
)}
// When filteredSeasonOptions is set through handleLeagueChange, show season combobox
{ filteredSeasonOptions && (
handleSeasonChange(value)}
onInputChange={
(inputValue) => {
setFilteredSeasonOptions(
setupSeasonSelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase()
)
);
}
}
/>
// When season is set through handleSeasonChange, show the "Fetch data" button
{
season && (
)
}
)}
اینم نتیجه!
ما با بلوک خود در مکان بسیار خوبی هستیم. ما می توانیم آن را در ویرایشگر بلوک و قسمت جلویی سایت رندر کنیم. میتوانیم براساس مجموعهای از تنظیماتی که ایجاد کردهایم و دادهها را فیلتر میکند، دادهها را از یک API خارجی واکشی کنیم. بسیار کاربردی است!
اما موضوع دیگری وجود دارد که باید به آن بپردازیم. در حال حاضر، وقتی صفحه یا پستی را که حاوی بلوک است ذخیره می کنیم، تنظیماتی که برای بلوک انتخاب کرده ایم بازنشانی می شود. به عبارت دیگر، آن انتخاب ها در هیچ کجا ذخیره نمی شوند. کمی کار بیشتر برای ماندگار کردن این انتخاب ها وجود دارد. اینجاست که قصد داریم در مقاله بعدی به آن برویم، پس با ما همراه باشید.