Like.js & Custom REST API Endpoints
Ringkasan
Video ini membahas pembuatan Like.js module untuk handle klik pada like box, serta pembuatan custom REST API endpoints menggunakan register_rest_route(). Kita juga belajar cara programmatically membuat post dengan wp_insert_post() dan mengirim data dari JavaScript ke server.
1. Like.js Module
File: src/modules/Like.js
import $ from 'jquery';
class Like {
constructor() {
this.events();
}
events() {
$(".like-box").on("click", this.ourClickDispatcher.bind(this));
}
// Methods
ourClickDispatcher(e) {
var currentLikeBox = $(e.target).closest(".like-box");
if (currentLikeBox.attr("data-exists") == "yes") {
this.deleteLike(currentLikeBox);
} else {
this.createLike(currentLikeBox);
}
}
createLike(currentLikeBox) {
// Akan diisi nanti
}
deleteLike(currentLikeBox) {
// Akan diisi nanti
}
}
export default Like;Import di index.js:
import Like from './modules/Like';
const like = new Like();Penjelasan ourClickDispatcher:
| Konsep | Penjelasan |
|---|---|
e.target | Elemen yang sebenarnya diklik (bisa icon, angka, atau span) |
.closest(".like-box") | Naik ke parent/grandparent terdekat yang match selector |
.attr("data-exists") | Baca atribut HTML secara fresh (bukan cache) |
.bind(this) | Pertahankan this menunjuk ke class instance |
Mengapa .attr() bukan .data()?
// ❌ jQuery .data() - membaca nilai SEKALI saat page load, lalu di-cache
currentLikeBox.data("exists")
// ✅ jQuery .attr() - selalu membaca nilai TERBARU dari DOM
currentLikeBox.attr("data-exists")
.data()tidak mendeteksi perubahan yang kita buat via.attr(). Untuk toggle like/unlike yang mengubah atribut secara real-time, kita HARUS pakai.attr().
2. Custom REST API Endpoints
Mengapa Custom Endpoint?
Default REST API endpoints (/wp/v2/like) hanya menyediakan CRUD dasar. Fitur like butuh custom logic:
- User harus login
- 1 like per user per professor
- Validasi bahwa ID adalah professor (bukan post/page/campus)
File: inc/like-route.php
<?php
add_action('rest_api_init', 'universityLikeRoutes');
function universityLikeRoutes() {
// Endpoint untuk CREATE like (POST request)
register_rest_route('university/v1', 'manageLike', array(
'methods' => 'POST',
'callback' => 'createLike'
));
// Endpoint untuk DELETE like (DELETE request)
register_rest_route('university/v1', 'manageLike', array(
'methods' => 'DELETE',
'callback' => 'deleteLike'
));
}
function createLike($data) {
// Akan diisi nanti
}
function deleteLike($data) {
// Akan diisi nanti
}Include di functions.php:
require get_theme_file_path('/inc/like-route.php');Penjelasan register_rest_route():
| Argumen | Nilai | Penjelasan |
|---|---|---|
| 1. Namespace | 'university/v1' | Prefix URL (bisa apa saja) |
| 2. Route | 'manageLike' | Nama endpoint |
| 3. Options | array(...) | Methods + callback |
URL yang Dihasilkan:
POST /wp-json/university/v1/manageLike → createLike()
DELETE /wp-json/university/v1/manageLike → deleteLike()Dua endpoint yang sama URL-nya tapi berbeda method (POST vs DELETE) → WordPress route ke callback yang berbeda.
3. JavaScript AJAX Request
Create Like:
createLike(currentLikeBox) {
$.ajax({
beforeSend: (xhr) => {
xhr.setRequestHeader('X-WP-Nonce', universityData.nonce);
},
url: universityData.root_url + '/wp-json/university/v1/manageLike',
type: 'POST',
data: {
professorId: currentLikeBox.data("professor")
},
success: (response) => {
// Real-time update — dibahas di file berikutnya
console.log(response);
},
error: (response) => {
console.log(response);
}
});
}Delete Like:
deleteLike(currentLikeBox) {
$.ajax({
beforeSend: (xhr) => {
xhr.setRequestHeader('X-WP-Nonce', universityData.nonce);
},
url: universityData.root_url + '/wp-json/university/v1/manageLike',
type: 'DELETE',
data: {
like: currentLikeBox.attr("data-like")
},
success: (response) => {
console.log(response);
},
error: (response) => {
console.log(response);
}
});
}4. Programmatically Create a Post: wp_insert_post()
File: inc/like-route.php — Fungsi createLike:
function createLike($data) {
if (is_user_logged_in()) {
$professor = sanitize_text_field($data['professorId']);
return wp_insert_post(array(
'post_type' => 'like',
'post_status' => 'publish',
'meta_input' => array(
'liked_professor_id' => $professor
)
));
} else {
die("Only logged in users can create a like.");
}
}Penjelasan wp_insert_post():
| Property | Nilai | Penjelasan |
|---|---|---|
post_type | 'like' | Jenis post yang dibuat |
post_status | 'publish' | Status langsung published (default: draft) |
post_title | opsional | Title (WP auto-generate jika kosong) |
post_content | opsional | Isi konten |
meta_input | array(...) | Custom fields (meta) yang ingin diset |
Property meta_input:
'meta_input' => array(
'liked_professor_id' => $professor, // key => value
// Bisa tambah field lain jika perlu
)- ACF plugin menggunakan nama yang sama untuk WordPress native meta fields
- Jadi
meta_inputbisa langsung mengisi ACF fields!
Return Value:
- Sukses: ID number dari post baru yang dibuat (misal
142) - Gagal:
0atauWP_Error
Menerima Data dari JavaScript:
function createLike($data) {
// $data berisi semua data yang dikirim dari JavaScript
// Baik dari property 'data' di $.ajax() maupun query string URL
$professor = sanitize_text_field($data['professorId']);
}Penting: Selalu
sanitize_text_field()semua input dari client sebelum digunakan!
5. Mengirim Data Professor ID dari JavaScript
Tambah Data Attribute pada HTML:
<!-- single-professor.php -->
<span class="like-box" data-professor="<?php the_ID(); ?>" ...>Akses di JavaScript:
data: {
professorId: currentLikeBox.data("professor")
}Dua Cara Mengirim Data (Equivalent):
// Cara 1: Property 'data' di $.ajax()
$.ajax({
url: '...',
data: { professorId: 123 }
});
// Cara 2: Query string di URL (sama hasilnya)
$.ajax({
url: '.../manageLike?professorId=123'
});Cara 1 lebih bersih dan terorganisir.