এখন পর্যন্ত, আমরা একটি কাস্টম ওয়ার্ডপ্রেস ব্লকে একটি বহিরাগত API থেকে ডেটা নিয়ে কীভাবে কাজ করতে হয় তা কভার করেছি। আমরা প্রক্রিয়ার মধ্য দিয়ে হেঁটেছি সামনের প্রান্তে ব্যবহারের জন্য সেই ডেটা আনা হচ্ছে একটি ওয়ার্ডপ্রেস সাইটের, এবং কিভাবে এটি সরাসরি ওয়ার্ডপ্রেস ব্লক এডিটরে রেন্ডার করুন বিষয়বস্তুতে ব্লক স্থাপন করার সময়। এইবার, আমরা যে ব্লকটি তৈরি করেছি তার জন্য একটি সেটিংস UI তৈরি করতে ব্লক সম্পাদকের কন্ট্রোল প্যানেলে হুক করে সেই দুটি নিবন্ধগুলিকে সেতু করতে যাচ্ছি।
ওয়ার্ডপ্রেস ব্লকে এক্সটার্নাল এপিআই এর সাথে কাজ করা
আমি যে কন্ট্রোল প্যানেলের কথা বলছি আপনি জানেন, তাই না? এটি ডানদিকের প্যানেল যা ব্লক সম্পাদকের পোস্ট এবং ব্লক সেটিংস ধারণ করে।
যে লাল হাইলাইট এলাকা দেখুন? এটাই কন্ট্রোল প্যানেল। একটি অনুচ্ছেদ ব্লক বর্তমানে নির্বাচন করা হয়েছে এবং এর জন্য সেটিংস প্যানেলে প্রদর্শিত হয়। আমরা শৈলী, রঙ, টাইপোগ্রাফি… অনেক কিছু পরিবর্তন করতে পারি!
ওয়েল, যে ঠিক কি আমরা এই সময় কাছাকাছি করছেন. আমরা ফুটবল র্যাঙ্কিং ব্লকের সেটিংসের জন্য নিয়ন্ত্রণ তৈরি করতে যাচ্ছি যা আমরা শেষ দুটি নিবন্ধে কাজ করেছি। গতবার, আমরা আমাদের ব্লকে একটি বোতাম তৈরি করেছি যা ফুটবল র্যাঙ্কিংয়ের জন্য বাহ্যিক ডেটা নিয়ে আসে। আমরা ইতিমধ্যেই আমাদের প্রয়োজনীয় URL এবং শেষ পয়েন্টগুলি জানতাম৷ কিন্তু যদি আমরা একটি ভিন্ন দেশের জন্য র্যাঙ্কিং আনতে চাই? নাকি ভিন্ন লিগ হতে পারে? কিভাবে একটি ভিন্ন ঋতু থেকে তথ্য সম্পর্কে?
এটা করার জন্য আমাদের ফর্ম কন্ট্রোল দরকার। আমরা ইন্টারেক্টিভ প্রতিক্রিয়া উপাদানগুলি ব্যবহার করতে পারি — যেমন প্রতিক্রিয়া-নির্বাচন করুন — সেই ডেটা পার্স করার জন্য উপলব্ধ বিভিন্ন API বিকল্পগুলির মাধ্যমে ব্রাউজ করতে। কিন্তু এর কোন প্রয়োজন নেই যেহেতু ওয়ার্ডপ্রেস একগুচ্ছ মূল উপাদানের সাথে শিপিং করে যা আমরা সরাসরি সংযুক্ত করি!
সার্জারির ডকুমেন্টেশন এই উপাদানগুলির জন্য - বলা হয় InspectorControls
-এ ভালো হচ্ছে ওয়ার্ডপ্রেস ব্লক এডিটর হ্যান্ডবুক. সময়ের সাথে সাথে এটি আরও ভাল হয়ে উঠবে, তবে এর মধ্যে, আমাদেরও রয়েছে ওয়ার্ডপ্রেস গুটেনবার্গ স্টোরিবুক এবং ওয়ার্ডপ্রেস গুটেনবার্গ উপাদান অতিরিক্ত সাহায্যের জন্য সাইট।
এপিআই আর্কিটেকচার
আমরা কোন কিছুর সাথে জড়িত হওয়ার আগে, প্রথমে আমাদের কী প্রয়োজন তা ম্যাপ করা একটি ভাল ধারণা। আমরা যে RapidAPI ডেটা আনছি তার কাঠামো আমি ম্যাপ করেছি যাতে আমরা জানতে পারি আমাদের কাছে কী উপলব্ধ:
ঋতু এবং দেশ দুটি শীর্ষ-স্তরের শেষ পয়েন্ট যা একটি লিগের শেষ পয়েন্টে মানচিত্র করে। সেখান থেকে, আমাদের কাছে বাকি ডেটা রয়েছে যা আমরা ইতিমধ্যেই র্যাঙ্কিং টেবিলটি পূরণ করতে ব্যবহার করছি। সুতরাং, আমরা যা করতে চাই তা হল ওয়ার্ডপ্রেস ব্লক এডিটরে সেটিংস তৈরি করে যা সিজন, দেশ এবং লীগ দ্বারা ডেটা ফিল্টার করে, তারপর সেই ফিল্টার করা ডেটা র্যাঙ্কিং টেবিলে পাস করে। এটি আমাদের যেকোনো ওয়ার্ডপ্রেস পৃষ্ঠা বা পোস্টে ব্লক ড্রপ করার ক্ষমতা দেয় এবং ব্লকে ডেটার বৈচিত্র প্রদর্শন করে।
স্ট্যান্ডিং পেতে, আমাদের প্রথমে লিগ পেতে হবে। এবং লিগ পেতে, আমাদের প্রথমে দেশ এবং/অথবা ঋতু পেতে হবে। আপনি RapidAPI ড্যাশবোর্ডে বিভিন্ন এন্ডপয়েন্ট দেখতে পারেন।
ডেটার বিভিন্ন সংমিশ্রণ রয়েছে যা আমরা র্যাঙ্কিং তৈরি করতে ব্যবহার করতে পারি এবং আপনি যে ডেটা চান তার জন্য আপনার পছন্দ থাকতে পারে। এই নিবন্ধটির জন্য, আমরা ব্লক সেটিংস প্যানেলে নিম্নলিখিত বিকল্পগুলি তৈরি করতে যাচ্ছি:
- দেশ পছন্দ করুন
- লীগ নির্বাচন করুন
- ঋতু চয়ন করুন
তারপরে সেই নির্বাচনগুলি জমা দেওয়ার এবং প্রাসঙ্গিক ডেটা আনতে এবং র্যাঙ্কিং টেবিলে পাস করার জন্য আমাদের কাছে একটি বোতাম থাকবে।
দেশের তালিকা লোড এবং সংরক্ষণ করুন
আমরা কোন দেশের জন্য ডেটা চাই তা নির্বাচন করতে পারি না যদি আমাদের কাছে বেছে নেওয়ার জন্য দেশের তালিকা না থাকে। সুতরাং, আমাদের প্রথম কাজ হল RapidAPI থেকে দেশগুলির একটি তালিকা নেওয়া।
আদর্শ জিনিস হল দেশের তালিকা আনয়ন করা যখন ব্লকটি আসলে পৃষ্ঠায় বা পোস্ট সামগ্রীতে ব্যবহার করা হয়। ব্লক ব্যবহার না হলে কিছু আনার দরকার নেই। পদ্ধতিটি আমরা যা করেছি তার সাথে খুব মিল প্রথম নিবন্ধ, পার্থক্য হল যে আমরা প্রত্যাবর্তিত দেশের তালিকা সংরক্ষণ করতে একটি ভিন্ন API এন্ডপয়েন্ট এবং বিভিন্ন বৈশিষ্ট্য ব্যবহার করছি। ডাটা আনার অন্যান্য ওয়ার্ডপ্রেস উপায় আছে, যেমন 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));
}, []);
দেশের তালিকা সংরক্ষণ করার জন্য আমাদের কাছে একটি রাষ্ট্রীয় পরিবর্তনশীল রয়েছে। পরবর্তী, আমরা থেকে একটি উপাদান আমদানি করতে যাচ্ছি @ওয়ার্ডপ্রেস/ব্লক-এডিটর প্যাকেজ বলা হয় InspectorControls
যেখানে আমাদের সেটিংস কন্ট্রোল তৈরি করতে আমাদের প্রয়োজনীয় সমস্ত উপাদান অবস্থিত।
import { InspectorControls } from "@wordpress/block-editor";
প্যাকেজ এর গিটহুব রেপো ব্যাখ্যা একটি ভাল কাজ করে InspectorControls
. আমাদের উদাহরণে, আমরা এপিআই ডেটা সেটিংস যেমন দেশ, লীগ এবং সিজন নিয়ন্ত্রণ করতে এটি ব্যবহার করতে পারি। আমরা যে 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
স্টেট কারণ আমরা থেকে আইডি বের করতে যাচ্ছি 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())
)
);
}}
/>
সার্জারির 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);
অন্যান্য সেটিংস বিকল্প সম্পর্কে কি?
আমি অন্যান্য সেটিংসের জন্য যে কোডটি ব্যবহার করেছি তা আমি দেখাব তবে বিশেষ ক্ষেত্রে ত্রুটিগুলি সংজ্ঞায়িত করার সময় এটি যা করে তা হল সাধারণ ক্ষেত্রে বিবেচনা করা। উদাহরণস্বরূপ, কিছু দেশ এবং লীগে ত্রুটি থাকবে কারণ:
- কিছু লিগের জন্য কোন স্ট্যান্ডিং নেই, এবং
- কিছু লিগের স্ট্যান্ডিং আছে কিন্তু তারা এক টেবিলে নেই।
এটি একটি জাভাস্ক্রিপ্ট বা প্রতিক্রিয়া টিউটোরিয়াল নয়, তাই আমি আপনাকে 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 থেকে ডেটা আনতে পারি। এটা বেশ দারুন কার্যকরী!
কিন্তু আরেকটি বিষয় আছে যা আমাদের মোকাবেলা করতে হবে। এই মুহুর্তে, যখন আমরা ব্লকটি ধারণ করা পৃষ্ঠা বা পোস্ট সংরক্ষণ করি, তখন আমরা ব্লক রিসেট করার জন্য যে সেটিংস নির্বাচন করি। অন্য কথায়, সেই নির্বাচনগুলি কোথাও সংরক্ষণ করা হয় না। সেই নির্বাচনগুলিকে স্থায়ী করতে আরও একটু কাজ করতে হবে। সেখানেই আমরা পরবর্তী নিবন্ধে যাওয়ার পরিকল্পনা করছি, তাই সাথে থাকুন।