1. Vì sao không nên render HTML trực tiếp từ shortcode?
- Không tối ưu hiệu suất: HTML render sẵn từ server khiến cache khó hoạt động.
- Không linh hoạt: Không thể tương tác động (pagination, filter, search…)
- Không tương thích SPA/PWA: Khi site chuyển sang hướng hiện đại, HTML “cứng” sẽ lỗi thời.
2. Ý tưởng tổng quát
Chúng ta sẽ:
- Tạo một shortcode nhận các thuộc tính như
post_type,number,category… - Shortcode render ra 1
<div>có ID cố định vàdata-*chứa config. - JavaScript đọc các config này, gọi REST API để lấy dữ liệu.
- Render kết quả bằng JS thuần, async hoàn toàn.
3. Tạo shortcode từ PHP
add_shortcode('modern_posts', function ($atts) {
$atts = shortcode_atts([
'post_type' => 'post',
'number' => 5,
'category' => '',
], $atts, 'modern_posts');
$json = esc_attr(json_encode($atts));
return '<div class="modern-posts" data-config="' . $json . '">Đang tải dữ liệu...</div>';
});
4. Tạo REST API endpoint
add_action('rest_api_init', function () {
register_rest_route('init/v1', '/modern-posts', [
'methods' => 'GET',
'callback' => 'get_modern_posts',
'permission_callback' => '__return_true',
]);
});
function get_modern_posts(WP_REST_Request $request) {
$args = [
'post_type' => $request->get_param('post_type') ?: 'post',
'posts_per_page' => intval($request->get_param('number')) ?: 5,
];
if ($cat = $request->get_param('category')) {
$args['category_name'] = sanitize_text_field($cat);
}
$query = new WP_Query($args);
$posts = [];
foreach ($query->posts as $post) {
$posts[] = [
'id' => $post->ID,
'title' => get_the_title($post),
'url' => get_permalink($post),
];
}
return rest_ensure_response($posts);
}
5. Viết JavaScript render async
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.modern-posts').forEach(function (el) {
const config = JSON.parse(el.dataset.config);
const params = new URLSearchParams(config).toString();
fetch(`/wp-json/init/v1/modern-posts?${params}`)
.then(res => res.json())
.then(data => {
if (!data.length) {
el.innerHTML = '<em>Không có bài viết nào.</em>';
return;
}
el.innerHTML = '<ul>' + data.map(p =>
'<li><a href="' + p.url + '">' + p.title + '</a></li>'
).join('') + '</ul>';
})
.catch(err => {
el.innerHTML = '<em>Lỗi tải dữ liệu.</em>';
console.error(err);
});
});
});
6. Tối ưu: enqueue script đúng cách
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script('modern-posts-script', plugin_dir_url(__FILE__) . 'assets/js/modern-posts.js', [], '1.0', true);
});
7. Kết luận
Viết shortcode kiểu mới không chỉ giúp plugin của bạn trở nên “hiện đại” mà còn dễ tích hợp với các frontend framework, tăng trải nghiệm người dùng, hỗ trợ tốt cho cache, và dễ mở rộng trong tương lai. Nếu bạn đang phát triển plugin hoặc theme, đừng ngại áp dụng cách làm này để hướng tới UX tốt nhất.
Bình luận