Memulai Plugin Featured Professor & Memuat Daftar Professor
Gambaran Umum
Dua video ini membahas pembuatan plugin Featured Professor dari awal — sebuah block type yang memungkinkan penulis blog menampilkan/meng-highlight seorang professor di dalam blog post. Dimulai dari boilerplate, membuat select dropdown, menyimpan attribute profId, lalu menggunakan useSelect hook untuk memuat daftar professor dari database.
Konsep Plugin Featured Professor
- Dari edit post screen, user bisa menambahkan block "Professor Callout"
- Block menampilkan select dropdown berisi semua professor post
- Setelah dipilih, muncul live preview professor di editor
- Di front-end, data ditampilkan secara dinamis (bukan snapshot statis)
- Hubungan dua arah: blog post → professor DAN professor → blog post
Setup Awal (Starter Files)
Struktur File
featured-professor/
├── src/
│ ├── index.js ← Edit component (admin)
│ └── index.scss ← Styling editor
├── inc/ ← File PHP terpisah (nanti)
├── build/ ← Auto-generated
├── featured-professor.php ← PHP plugin utama
└── package.jsonFile PHP Utama (featured-professor.php)
<?php
/*
Plugin Name: Featured Professor Block Type
*/
if (!defined('ABSPATH')) exit;
class FeaturedProfessor {
function __construct() {
add_action('init', [$this, 'onInit']);
}
function onInit() {
wp_register_script('featuredProfessorScript', plugin_dir_url(__FILE__) . 'build/index.js', array('wp-blocks', 'wp-element', 'wp-editor'));
wp_register_style('featuredProfessorStyle', plugin_dir_url(__FILE__) . 'build/index.css');
register_block_type('ourplugin/featured-professor', array(
'editor_script' => 'featuredProfessorScript',
'editor_style' => 'featuredProfessorStyle',
'render_callback' => [$this, 'renderCallback']
));
}
function renderCallback($attributes) {
return '<p>We will replace this content soon.</p>';
}
}
new FeaturedProfessor();Install Dependencies & Build
npm init -y
npm install @wordpress/scriptsDi package.json, tambahkan scripts:
{
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
}
}npm run startMembuat Select Dropdown dengan Attribute
Mendaftarkan Attribute profId
wp.blocks.registerBlockType('ourplugin/featured-professor', {
title: 'Professor Callout',
icon: 'welcome-learn-more',
category: 'common',
attributes: {
profId: { type: 'string' } // String untuk kompatibilitas WP
},
edit: EditComponent,
save: function() {
return null;
}
});Tips: Meskipun post ID adalah angka, gunakan
type: 'string'— WordPress menyimpan dan membandingkan data sebagai string dari database, jadistringlebih reliable.
Edit Component dengan Select Element
function EditComponent(props) {
return (
<div className="featured-professor-wrapper">
<div className="professor-select-container">
<select onChange={e => props.setAttributes({ profId: e.target.value })}>
<option>Select a professor</option>
<option value="1" selected={props.attributes.profId == "1"}>1</option>
<option value="2" selected={props.attributes.profId == "2"}>2</option>
<option value="3" selected={props.attributes.profId == "3"}>3</option>
</select>
</div>
<div>HTML preview will go here.</div>
</div>
);
}onChange→ simpan value ke attributeprofIdselected→ bandingkanprops.attributes.profIduntuk menandai opsi yang dipilih- Data tersimpan di database sebagai block comment:
<!-- wp:ourplugin/featured-professor {"profId":"43"} -->
Memuat Daftar Professor dengan useSelect
Konsep: WordPress Data Layer
Di console browser, kita bisa mengakses data WordPress:
wp.data.select('core').getEntityRecords('postType', 'professor', { per_page: -1 })- Pertama kali dipanggil → return
null(asynchronous) - Kedua kali → return array of professor posts
-1padaper_page= ambil semua post sekaligus
Menggunakan useSelect Hook
Import dari @wordpress/data:
import { useSelect } from "@wordpress/data"Di dalam Edit Component:
function EditComponent(props) {
const allProfs = useSelect(function(select) {
return select('core').getEntityRecords('postType', 'professor', { per_page: -1 });
});
// Loading state
if (allProfs == undefined) {
return <p>Loading...</p>;
}
return (
<div className="featured-professor-wrapper">
<div className="professor-select-container">
<select onChange={e => props.setAttributes({ profId: e.target.value })}>
<option>Select a professor</option>
{allProfs.map(prof => {
return (
<option value={prof.id} selected={props.attributes.profId == prof.id}>
{prof.title.rendered}
</option>
);
})}
</select>
</div>
<div>HTML preview will go here.</div>
</div>
);
}Cara Kerja useSelect
- Pertama kali render →
allProfs=undefined→ tampilkan "Loading..." - Setelah data tersedia →
useSelectotomatis re-run function →allProfs= array of posts - Component re-render otomatis karena data berubah
- Select dropdown terisi dengan nama-nama professor dari
prof.title.rendered - Value setiap option =
prof.id(post ID numerik)
Struktur Data dari getEntityRecords
[
{
id: 43,
title: { rendered: "Dr. Barks A Lot" },
content: { rendered: "..." },
// ... properti lainnya
},
// ...
]Poin Penting:
useSelectmenangani semua kompleksitas asynchronous — kita tidak perlu manual fetch atau manage promise/callback.