จนถึงตอนนี้ เราได้กล่าวถึงวิธีการทำงานกับข้อมูลจาก API ภายนอกในบล็อก WordPress แบบกำหนดเอง เราเดินผ่านกระบวนการของ ดึงข้อมูลนั้นมาใช้ในส่วนหน้า ของเว็บไซต์ WordPress และวิธีการ แสดงผลโดยตรงใน WordPress Block Editor เมื่อวางบล็อกในเนื้อหา ในครั้งนี้ เราจะเชื่อมโยงบทความทั้งสองเข้าด้วยกันโดยเชื่อมต่อกับแผงควบคุมของเครื่องมือแก้ไขบล็อกเพื่อสร้าง UI การตั้งค่าสำหรับบล็อกที่เราสร้างขึ้น
การทำงานกับ API ภายนอกใน WordPress Blocks
คุณรู้จักแผงควบคุมที่ฉันหมายถึงใช่ไหม เป็นแผงด้านขวาที่มีการตั้งค่าโพสต์และบล็อกในตัวแก้ไขบล็อก
เห็นพื้นที่ไฮไลท์สีแดงนั้นไหม? นั่นคือแผงควบคุม ขณะนี้บล็อกย่อหน้าถูกเลือกและการตั้งค่าจะแสดงในแผง เราสามารถเปลี่ยนรูปแบบ สี รูปแบบตัวอักษร... ได้หลายอย่าง!
นั่นคือสิ่งที่เรากำลังทำในครั้งนี้ เราจะสร้างการควบคุมสำหรับการตั้งค่าบล็อกอันดับฟุตบอลที่เราทำในสองบทความล่าสุด คราวที่แล้ว เราสร้างปุ่มในบล็อกของเราเพื่อดึงข้อมูลภายนอกสำหรับการจัดอันดับฟุตบอล เรารู้ URL และปลายทางที่เราต้องการแล้ว แต่ถ้าเราต้องการดึงอันดับของประเทศอื่นล่ะ? หรืออาจจะเป็นลีกอื่น? แล้วข้อมูลจากฤดูกาลอื่นล่ะ?
เราต้องการตัวควบคุมฟอร์มเพื่อทำเช่นนั้น เราสามารถใช้ส่วนประกอบ React แบบโต้ตอบได้ เช่น ตอบสนอง-เลือก — เพื่อเรียกดูผ่านตัวเลือก API ต่างๆ ที่มีให้เพื่อแยกวิเคราะห์ข้อมูลนั้น แต่ก็ไม่จำเป็นสำหรับสิ่งนั้นเนื่องจาก WordPress มาพร้อมกับองค์ประกอบหลักมากมายที่เราเชื่อมโยงเข้าด้วยกัน!
พื้นที่ เอกสาร สำหรับส่วนประกอบเหล่านี้เรียกว่า InspectorControls
- เริ่มดีขึ้นใน คู่มือ WordPress Block Editor. ซึ่งจะดียิ่งขึ้นเมื่อเวลาผ่านไป แต่ในขณะเดียวกัน เราก็มี WordPress หนังสือนิทาน Gutenberg และ ส่วนประกอบ WordPress Gutenberg ไซต์สำหรับความช่วยเหลือเพิ่มเติม
สถาปัตยกรรม API
ก่อนที่เราจะเชื่อมโยงสิ่งใดสิ่งหนึ่ง คุณควรวางแผนว่าเราต้องการอะไรก่อนเป็นอันดับแรก ฉันได้แมปโครงสร้างของข้อมูล RapidAPI ที่เรากำลังดึงมา เพื่อให้เรารู้ว่ามีอะไรให้เราบ้าง:
ฤดูกาลและประเทศเป็นจุดสิ้นสุดระดับบนสุดสองจุดที่จับคู่กับจุดสิ้นสุดของลีก จากตรงนั้น เรามีข้อมูลที่เหลือซึ่งเราใช้อยู่แล้วเพื่อเติมข้อมูลในตารางอันดับ ดังนั้น สิ่งที่เราต้องการทำคือสร้างการตั้งค่าใน WordPress Block Editor ที่กรองข้อมูลตามฤดูกาล ประเทศ และลีก จากนั้นส่งข้อมูลที่กรองแล้วไปยังตารางอันดับ นั่นทำให้เราสามารถวางบล็อกในหน้าหรือโพสต์ของ WordPress และแสดงรูปแบบต่างๆ ของข้อมูลในบล็อกได้
เพื่อให้ได้อันดับ เราต้องได้อันดับลีกก่อน และเพื่อที่จะได้ลีก เราต้องได้ประเทศและ/หรือฤดูกาลก่อน คุณสามารถดูปลายทางต่างๆ ได้ในแดชบอร์ด RapidAPI
มีชุดข้อมูลต่างๆ มากมายที่เราสามารถใช้เพื่อเติมข้อมูลในการจัดอันดับ และคุณอาจมีการตั้งค่าว่าข้อมูลใดที่คุณต้องการ เพื่อประโยชน์ของบทความนี้ เราจะสร้างตัวเลือกต่อไปนี้ในแผงการตั้งค่าการบล็อก:
- เลือกประเทศ
- เลือกลีก
- เลือกซีซัน
จากนั้นเราจะมีปุ่มสำหรับส่งการเลือกเหล่านั้นและดึงข้อมูลที่เกี่ยวข้องและส่งไปยังตารางอันดับ
โหลดและจัดเก็บรายชื่อประเทศ
เราไม่สามารถเลือกประเทศที่เราต้องการข้อมูลได้หากเราไม่มีรายชื่อประเทศให้เลือก ดังนั้น งานแรกของเราคือคว้ารายชื่อประเทศจาก RapidAPI
สิ่งที่ดีที่สุดคือการดึงรายชื่อประเทศเมื่อมีการใช้บล็อกในหน้าหรือเนื้อหาโพสต์ ไม่จำเป็นต้องดึงข้อมูลใดๆ หากไม่มีการใช้งานบล็อก วิธีการนี้คล้ายกับที่เราทำใน บทความแรกความแตกต่างคือเราใช้ตำแหน่งข้อมูล API ที่แตกต่างกันและแอตทริบิวต์ที่แตกต่างกันเพื่อจัดเก็บรายชื่อประเทศที่ส่งคืน มีวิธีอื่นๆ ของ WordPress ในการดึงข้อมูล เช่น api-ดึงข้อมูลแต่นั่นอยู่นอกขอบเขตของสิ่งที่เรากำลังทำอยู่นี้
เราสามารถรวมรายชื่อประเทศด้วยตนเองหลังจากคัดลอกจากข้อมูล 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";
แพคเกจของ repo GitHub ทำหน้าที่อธิบายได้ดี InspectorControls
. ในตัวอย่างของเรา เราสามารถใช้มันเพื่อควบคุมการตั้งค่าข้อมูล API เช่น ประเทศ ลีก และฤดูกาล นี่คือการแสดงตัวอย่างเพื่อให้คุณเข้าใจถึง UI ที่เรากำลังสร้าง:
และเมื่อทำการเลือกเหล่านั้นในการตั้งค่าบล็อกแล้ว เราจะนำไปใช้ใน บล็อกของ Edit
ฟังก์ชัน:
{ countriesList && (
)}
ที่นี่ ฉันแน่ใจว่าเรากำลังใช้การเรนเดอร์แบบมีเงื่อนไขเพื่อให้ฟังก์ชันโหลดเฉพาะคอมโพเนนต์ หลังจาก โหลดรายชื่อประเทศแล้ว หากคุณสงสัยเกี่ยวกับเรื่องนั้น LeagueSettings
คอมโพเนนต์ เป็นคอมโพเนนต์แบบกำหนดเองที่ฉันสร้างแยกต่างหาก components
โฟลเดอร์ย่อยในบล็อกเพื่อให้เราสะอาดและเป็นระเบียบมากขึ้น Edit
แทนข้อมูลประเทศหลายร้อยบรรทัดเพื่อจัดการในไฟล์เดียว
เราสามารถนำเข้าสู่ edit.js
ไฟล์เช่นนี้:
import { LeagueSettings } from "./components/LeagueSettings";
ต่อไป เรากำลังส่งอุปกรณ์ประกอบฉากที่จำเป็นไปยัง LeagueSettings
ส่วนประกอบจากผู้ปกครอง Edit
เพื่อให้เราสามารถเข้าถึงตัวแปรสถานะและแอตทริบิวต์จาก LeagueSettings
องค์ประกอบลูก เราสามารถทำได้ด้วยวิธีอื่นๆ เช่น บริบท API เพื่อหลีกเลี่ยงการเจาะเสา แต่สิ่งที่เรามีตอนนี้เหมาะสมอย่างยิ่งกับสิ่งที่เรากำลังทำอยู่
ส่วนอื่นๆ ของ Edit
ฟังก์ชั่นยังสามารถแปลงเป็นส่วนประกอบ ตัวอย่างเช่น รหัสอันดับของลีกสามารถใส่ไว้ในองค์ประกอบแยกต่างหากได้ เช่น อาจจะ LeagueTable.js
— แล้วนำเข้าเหมือนที่เรานำเข้า LeagueSettings
เข้าไปใน Edit
ฟังก์ชัน
LeagueSettings.js
ไฟล์
ภายใน LeagueSettings
ก็เหมือนกับอีกคนหนึ่ง องค์ประกอบปฏิกิริยา ซึ่งเราสามารถทำลายอุปกรณ์ประกอบฉากจากส่วนประกอบหลักได้ ฉันจะใช้ตัวแปรสถานะสามตัวและตัวแปรเพิ่มเติม leagueID
รัฐเนื่องจากเราจะแยก ID จาก 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
ซึ่งเอกสารอธิบายว่าเป็น "เวอร์ชันปรับปรุงของ SelectControl
ด้วยความสามารถในการค้นหาตัวเลือกโดยใช้การป้อนข้อมูลการค้นหาเพิ่มเติม” เป็นเรื่องดีสำหรับเราเพราะรายชื่อประเทศอาจค่อนข้างยาว และผู้ใช้จะสามารถเลือกค้นหาหรือเลือกจากรายการก็ได้
นี่คือตัวอย่างว่าก ComboboxControl
สามารถใช้ได้กับรายชื่อประเทศของเรา:
handleCountryChange(value) }
onInputChange={ (inputValue) => {
setFilteredCountryOptions(
setupCountrySelect.filter((option) =>
option.label
.toLowerCase()
.startsWith(inputValue.toLowerCase())
)
);
}}
/>
พื้นที่ 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);
แล้วตัวเลือกการตั้งค่าอื่นๆ ล่ะ?
ฉันจะแสดงรหัสที่ฉันใช้สำหรับการตั้งค่าอื่น ๆ แต่ทั้งหมดนั้นต้องคำนึงถึงกรณีปกติในขณะที่กำหนดข้อผิดพลาดสำหรับกรณีพิเศษ ตัวอย่างเช่น จะมีข้อผิดพลาดในบางประเทศและบางลีกเนื่องจาก:
- ไม่มีอันดับสำหรับบางลีกและ
- บางลีกมีอันดับแต่ไม่ได้อยู่ในตารางเดียว
นี่ไม่ใช่บทช่วยสอน JavaScript หรือ 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);
}
ส่งการเลือกการตั้งค่า
ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร บทความล่าสุดเราสร้างปุ่มในตัวแก้ไขบล็อกที่ดึงข้อมูลใหม่จาก 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 ภายนอกตามการเลือกการตั้งค่าที่เราสร้างขึ้นซึ่งกรองข้อมูล มันใช้งานได้ดีมาก!
แต่มีอีกสิ่งหนึ่งที่เราต้องจัดการ ในตอนนี้ เมื่อเราบันทึกเพจหรือโพสต์ที่มีการบล็อก การตั้งค่าที่เราเลือกสำหรับการบล็อกจะรีเซ็ต กล่าวอีกนัยหนึ่ง การเลือกเหล่านั้นจะไม่ถูกบันทึกไว้ที่ใดก็ได้ มีงานอีกเล็กน้อยที่จะทำให้การเลือกเหล่านั้นคงอยู่ นั่นคือจุดที่เราวางแผนจะไปในบทความหน้า โปรดคอยติดตาม