Bỏ qua tới nội dung
WordPress· ·10 phút đọc

Tạo custom block cho FSE từ block.json đến đăng ký

Nguyễn Quốc An
Tạo custom block cho FSE từ block.json đến đăng ký
Cỡ chữ

Khi đã chuyển sang chỉnh sửa toàn trang (FSE — full site editing, chỉnh sửa toàn bộ giao diện bằng khối), bạn sẽ gặp lúc các khối có sẵn của WordPress không đủ. Đó là lúc cần một khối tự viết. Bài này đi qua đúng quy trình tạo một khối từ con số không, phân biệt hai kiểu render, và quan trọng nhất là giúp bạn quyết định khi nào thực sự cần viết khối thay vì dùng giải pháp nhẹ hơn.

Custom block khác block pattern ở đâu

Nhiều người lẫn lộn hai thứ này vì cùng nằm trong bộ chèn khối. Nhưng bản chất rất khác:

  • Block pattern (mẫu khối) chỉ là một tổ hợp các khối có sẵn được gói lại để chèn nhanh. Sau khi chèn, nó tan ra thành các khối thường, người dùng sửa thoải mái. Không có logic, không có PHP, không có JavaScript riêng.
  • Custom block (khối tuỳ biến) là một loại khối mới hẳn, có tên riêng, có thuộc tính (attributes — dữ liệu khối lưu lại), có giao diện chỉnh riêng trong sidebar, và có thể chạy logic động.

Quy tắc thực dụng: nếu thứ bạn cần chỉ là một bố cục cố định ghép từ các khối sẵn có (một khối hero, một dải đánh giá, một cụm nút), hãy làm block pattern dựng sẵn cho theme — nhanh hơn, không cần build. Chỉ viết custom block khi bạn cần dữ liệu động (danh sách bài mới, giá lấy từ API), một control chỉnh riêng, hoặc một hành vi mà các khối lõi không làm được.

So sánh custom block và block pattern trong WordPress
Custom block là khối mới có logic, pattern chỉ là tổ hợp khối sẵn có.

Dựng khung bằng create-block

Công cụ chính thống để tạo khung là @wordpress/create-block. Nó sinh sẵn cấu trúc thư mục, tệp block.json, cấu hình build và mã mẫu, để bạn không phải dựng tay từ đầu. Mở terminal ở thư mục wp-content/plugins rồi chạy:

npx @wordpress/create-block bao-gia-block

Lệnh này tạo một plugin chứa khối tĩnh. Nếu muốn khối render động ngay từ đầu, thêm cờ biến thể:

npx @wordpress/create-block bao-gia-block --variant dynamic

Sau đó vào thư mục plugin và chạy build. Lệnh start theo dõi thay đổi và biên dịch lại trong lúc phát triển:

cd bao-gia-block
npm install
npm run start

Kích hoạt plugin trong wp-admin là khối đã hiện trong bộ chèn. Trong trải nghiệm tự code plugin theo yêu cầu tại Web22, đặt mỗi custom block trong một plugin riêng (thay vì nhồi vào theme) giúp khối sống sót khi đổi giao diện — đây là điểm quan trọng dễ bị bỏ qua.

block.json — trái tim của khối

Mọi thông tin về khối nằm trong block.json. WordPress đọc tệp này ở cả phía máy chủ lẫn trình duyệt, nên bạn chỉ khai báo một nơi duy nhất. Một tệp tối giản:

{
  "$schema": "https://schemas.wp.org/trunk/block.json",
  "apiVersion": 3,
  "name": "web22/bao-gia",
  "title": "Bảng báo giá",
  "category": "widgets",
  "icon": "money-alt",
  "description": "Khối hiển thị bảng giá dịch vụ.",
  "attributes": {
    "tieuDe": { "type": "string", "default": "Báo giá" }
  },
  "supports": { "html": false },
  "textdomain": "bao-gia-block",
  "editorScript": "file:./index.js",
  "style": "file:./style-index.css",
  "render": "file:./render.php"
}

Vài trường đáng lưu ý: apiVersion nên là 3 cho khối hiện đại; name bắt buộc có tiền tố không gian tên (namespace) để tránh trùng; attributes khai báo dữ liệu khối lưu; và dòng render trỏ tới tệp PHP — chính dòng này biến khối thành động.

Static block và dynamic block — chọn loại nào

Đây là quyết định kiến trúc quan trọng nhất.

Static block (khối tĩnh)

Khối tĩnh lưu thẳng HTML vào nội dung bài lúc lưu bài. Hàm save trong JavaScript quyết định HTML đó. Ưu điểm: nhanh khi hiển thị (không cần xử lý lúc tải trang), không phụ thuộc PHP. Hợp với nội dung không đổi: một khung trích dẫn, một dải lời chứng thực cố định.

Dynamic block (khối động)

Khối động không lưu HTML cố định. Mỗi lần trang tải, WordPress chạy PHP để sinh HTML mới. Hợp với dữ liệu thay đổi theo thời gian: danh sách bài viết mới nhất, số liệu lấy từ cơ sở dữ liệu, giá cập nhật. Tệp render.php nhận biến $attributes, $content$block:

<?php
// render.php
$tieu_de = $attributes['tieuDe'] ?? 'Báo giá';
?>
<div <?php echo get_block_wrapper_attributes(); ?>>
  <h3><?php echo esc_html( $tieu_de ); ?></h3>
  <p>Cập nhật ngày <?php echo esc_html( date_i18n( 'd/m/Y' ) ); ?></p>
</div>

Hàm get_block_wrapper_attributes() tự gắn các class và style mà người dùng chọn trong trình soạn thảo — bỏ qua nó là mất phần căn lề, màu nền họ đã set. Luôn dùng esc_html() hay esc_attr() khi in dữ liệu để chống chèn mã độc.

Đăng ký khối với register_block_type

Dù tĩnh hay động, khối đều phải được đăng ký phía máy chủ trên hook init. Nhờ block.json, bạn chỉ cần trỏ tới thư mục build (nơi quá trình biên dịch đặt tệp đã build):

<?php
function web22_dang_ky_block() {
    register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'web22_dang_ky_block' );

WordPress tự đọc block.json trong thư mục đó, tự nạp script, style và tệp render.php nếu có. Bạn không cần khai báo render_callback bằng tay nữa — đó là cách cũ trước WordPress 6.1. Nắm chắc cơ chế hook và thứ tự nạp trong WordPress giúp bạn hiểu vì sao phải gắn vào init chứ không phải nơi khác.

Từ WordPress 6.8, nếu plugin có hàng chục khối, có cách gọi gộp qua tệp manifest để giảm số lần đọc tệp. Nhưng với một vài khối, cách trỏ thư mục ở trên là đủ rõ ràng và dễ bảo trì.

Sơ đồ các bước tạo một custom block cho FSE
Quy trình tạo khối tuỳ biến từ dựng khung đến đăng ký và kiểm tra.

Các bước gọn lại

  1. Chạy create-block để dựng khung (thêm --variant dynamic nếu cần khối động).
  2. npm install rồi npm run start để build và theo dõi thay đổi.
  3. Khai báo tên, thuộc tính, icon, đường dẫn render trong block.json.
  4. Viết render.php cho khối động, hoặc hàm save cho khối tĩnh.
  5. Đăng ký bằng register_block_type( __DIR__ . '/build' ) trên hook init.
  6. Kích hoạt plugin, kiểm tra khối trong cả trình soạn thảo lẫn mặt trước.

Khi khối đã chạy ổn, đừng quên kiểm tra cẩn thận phần thoát ký tự và quyền truy cập dữ liệu — đây là nơi quy tắc viết code WordPress an toàn phát huy giá trị.

Câu hỏi thường gặp

Custom block có cần build không?

Khối viết bằng JSX (cú pháp React) cần build vì trình duyệt không hiểu JSX trực tiếp. Đó là lý do create-block đi kèm cấu hình biên dịch. Có thể viết khối không cần build bằng JavaScript thuần, nhưng đa số dự án dùng JSX cho gọn.

Khi nào chọn dynamic thay vì static?

Chọn động khi nội dung thay đổi sau lúc lưu bài: dữ liệu từ cơ sở dữ liệu, danh sách bài mới, giá cập nhật. Chọn tĩnh khi nội dung cố định để hiển thị nhanh và không phụ thuộc PHP.

Custom block có thay được mọi block pattern không?

Không nên. Nếu chỉ cần ghép các khối sẵn có thành bố cục cố định thì block pattern nhẹ và nhanh hơn nhiều. Custom block dành cho khi cần dữ liệu động hoặc hành vi riêng.

Nếu bạn đang xây giao diện block theme mà thấy cần khối riêng nhưng chưa chắc nên tự viết hay dùng pattern, dịch vụ phát triển theme WordPress theo yêu cầu của Web22 có thể giúp bạn cân nhắc đúng hướng trước khi đổ công sức.

Cần làm web?

Dịch vụ liên quan
tới chủ đề bài này.

Tất cả dịch vụ
Đọc tiếp

Bài viết
cùng chủ đề.

Tất cả bài viết