Tài liệu tham khảo toàn tập về Hooks & Filters trong PolyCMS
Last updated on Jul 10, 2026 4:19 AM
Tổng quan
PolyCMS cung cấp hệ thống Hook và Filter được lấy cảm hứng từ WordPress, cho phép các nhà phát triển mở rộng tính năng của hệ thống mà không cần can thiệp hay sửa đổi trực tiếp các file mã nguồn cốt lõi của mô-đun. Đây chính là nền tảng cốt lõi phục vụ việc tự xây dựng plugin tùy biến và thiết lập các giao diện theme riêng.
Hệ thống có hai loại điểm neo (hooks):
- Actions (Hành động) — Thực thi một đoạn mã tùy biến tại các mốc thời gian cụ thể của hệ thống (ví dụ: gửi mail ngay sau khi bài viết được lưu thành công).
- Filters (Bộ lọc) — Chỉnh sửa hoặc biến đổi dữ liệu trước khi dữ liệu được sử dụng hoặc ghi vào database (ví dụ: thay đổi tiêu đề bài viết trước khi render hiển thị ra màn hình).
Các hàm API cốt lõi
Đăng ký một Action
polycms_add_action(string $hook, callable $callback, int $priority = 10, int $args = 1);Giải thích tham số:
$hook— Tên gọi của action hook hệ thống.$callback— Hàm hoặc phương thức sẽ được gọi thực thi.$priority— Thứ tự ưu tiên thực thi (số càng nhỏ sẽ chạy càng sớm). Giá trị mặc định:10.$args— Số lượng tham số truyền vào hàm callback. Giá trị mặc định:1.
Ví dụ mẫu:
// Tự động gửi tin nhắn thông báo Slack ngay khi xuất bản bài viết mới
polycms_add_action('polycms_post_published', function($post) {
$message = "New post published: {$post->title}";
send_slack_notification($message);
}, 10, 1);Đăng ký một Filter
polycms_add_filter(string $hook, callable $callback, int $priority = 10, int $args = 1);Các hàm callback của Filter **bắt buộc phải trả về (return)** giá trị sau khi đã xử lý biến đổi.
Ví dụ mẫu:
// Tự động chèn thêm ghi chú bản quyền ở cuối mỗi bài viết
polycms_add_filter('polycms_post_content', function($content) {
return $content . '<p class="disclaimer"><em>Bài viết thuộc bản quyền của tác giả.</em></p>';
}, 20, 1);Cách kích hoạt các điểm neo
// Kích hoạt một Action
polycms_do_action(string $hook, ...$args);
// Thực thi một Filter
$value = polycms_apply_filters(string $hook, $value, ...$args);Tài liệu danh sách đầy đủ các Hooks hệ thống
Vòng đời của Bài viết (Post Lifecycle Actions)
| Tên Hook | Thời điểm kích hoạt | Các tham số truyền vào |
|---|---|---|
polycms_post_save | Trước khi bản ghi bài viết được lưu vào cơ sở dữ liệu | $data (mảng dữ liệu) |
polycms_post_saved | Sau khi lưu bài viết thành công | $post (đối tượng bài viết) |
polycms_post_published | Khi trạng thái bài viết chuyển sang xuất bản (published) | $post (đối tượng bài viết) |
polycms_post_delete | Trước khi bài viết bị xóa khỏi hệ thống | $post_id (ID bài viết) |
polycms_post_deleted | Sau khi bài viết đã được xóa thành công | $post_id (ID bài viết) |
polycms_post_status_changed | Khi trạng thái bài viết thay đổi | $post, $old_status, $new_status |
Vòng đời của Trang tĩnh (Page Lifecycle Actions)
| Tên Hook | Thời điểm kích hoạt | Các tham số truyền vào |
|---|---|---|
polycms_page_saved | Sau khi lưu trang tĩnh thành công | $page (đối tượng trang) |
polycms_page_deleted | Sau khi xóa trang tĩnh thành công | $page_id (ID trang) |
Các hoạt động về Bình luận (Comment Actions)
| Tên Hook | Thời điểm kích hoạt | Các tham số truyền vào |
|---|---|---|
polycms_comment_submitted | Khi độc giả vừa gửi một bình luận mới | $comment (đối tượng bình luận) |
polycms_comment_approved | Khi bình luận được duyệt hiển thị | $comment (đối tượng bình luận) |
polycms_comment_deleted | Khi bình luận bị xóa khỏi hệ thống | $comment_id (ID bình luận) |
Hiển thị và kết xuất giao diện (Frontend Rendering Actions)
| Tên Hook | Thời điểm kích hoạt | Các tham số truyền vào |
|---|---|---|
polycms_head | Nằm bên trong thẻ mở <head> của trang ngoài | Không có |
polycms_footer | Nằm ngay trước thẻ đóng </body> của trang ngoài | Không có |
polycms_frontend_init | Khi controller frontend khởi động thiết lập ban đầu | Không có |
polycms_before_render_post | Trước khi kết xuất giao diện chi tiết một bài viết | $post (đối tượng bài viết) |
polycms_after_render_post | Sau khi kết xuất giao diện bài viết xong | $post, $output (mã HTML đầu ra) |
polycms_after_render_homepage | Sau khi kết xuất giao diện trang chủ blog | $output (mã HTML đầu ra) |
polycms_admin_bar_actions | Hỗ trợ chèn các nút thao tác tùy biến trên thanh admin bar ngoài trang chủ | Không có |
Bộ lọc nội dung (Content Filters)
| Tên Filter | Đối tượng tác động | Tham số truyền vào | Kết quả trả về kỳ vọng |
|---|---|---|---|
polycms_post_content | Toàn bộ nội dung văn bản chi tiết bài viết | $content (chuỗi HTML) | Nội dung sau khi đã chỉnh sửa |
polycms_post_title | Tiêu đề bài viết | $title (chuỗi tiêu đề) | Tiêu đề sau khi đã chỉnh sửa |
polycms_post_excerpt | Nội dung mô tả ngắn bài viết | $excerpt (chuỗi mô tả) | Mô tả sau khi đã chỉnh sửa |
polycms_page_content | Toàn bộ nội dung chi tiết trang tĩnh | $content (chuỗi HTML) | Nội dung trang sau khi chỉnh sửa |
polycms_post_meta | Thông tin siêu dữ liệu bài viết | $meta (mảng meta) | Mảng dữ liệu sau khi sửa đổi |
Bộ lọc tối ưu hóa SEO (SEO Filters)
| Tên Filter | Đối tượng tác động | Tham số đầu vào |
|---|---|---|
polycms_meta_title | Thẻ tiêu đề meta cuối cùng (meta title tag) | $title (chuỗi tiêu đề) |
polycms_meta_description | Thẻ mô tả meta (meta description) | $description (chuỗi mô tả) |
polycms_og_tags | Mảng chứa các thẻ định dạng Open Graph (Facebook) | $tags (mảng tag) |
polycms_twitter_tags | Mảng chứa các thẻ định dạng Twitter Cards | $tags (mảng tag) |
Hoạt động Plugin & Theme (Plugin & Theme Actions)
| Tên Hook | Thời điểm kích hoạt | Các tham số truyền vào |
|---|---|---|
polycms_plugin_activated | Khi một plugin được kích hoạt thành công | $plugin_slug (Mã định danh plugin) |
polycms_plugin_deactivated | Khi một plugin bị tạm tắt thành công | $plugin_slug (Mã định danh plugin) |
polycms_theme_switched | Khi thay đổi giao diện hoạt động của blog | $new_theme, $old_theme (Tên giao diện mới và cũ) |
Các ví dụ lập trình thực tế
Ví dụ 1: Tự động trích xuất nội dung ngắn (Auto-Excerpt)
polycms_add_filter('polycms_post_excerpt', function($excerpt) {
if (empty($excerpt)) {
$CI = &get_instance();
$content = $CI->load->get_var('post')->content ?? '';
return mb_substr(strip_tags($content), 0, 160) . '...';
}
return $excerpt;
});Ví dụ 2: Nhúng mã đo lường Google Tag Manager
polycms_add_action('polycms_head', function() {
$gtm_id = get_option('polycms_gtm_id');
if ($gtm_id) {
echo "<script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','{$gtm_id}');</script>";
}
});Ví dụ 3: Giới hạn quyền đọc bài viết riêng tư cho nhân viên
polycms_add_filter('polycms_post_content', function($content) {
$CI = &get_instance();
$post = $CI->load->get_var('post');
if ($post->visibility === 'private' && !is_staff_logged_in()) {
return '<div class="restricted"><p>Nội dung này chỉ dành riêng cho các thành viên quản trị.</p></div>';
}
return $content;
});Các nguyên tắc phát triển cần lưu ý
- Luôn khai báo tham số độ ưu tiên để chủ động điều phối thứ tự chạy code của bạn. Độ ưu tiên mặc định là
10. - Filter bắt buộc phải trả về giá trị — việc bỏ quên lệnh
returnsẽ làm mất chuỗi truyền tải dữ liệu và gây lỗi hiển thị. - Sử dụng các tên hàm có tính phân loại cao (như thêm tiền tố riêng) hoặc sử dụng hàm nặc danh (closures) để tránh lỗi trùng lặp tên hàm giữa các plugin.
- Không thay đổi trạng thái toàn cục khi đang xử lý filter — chỉ nên tập trung xử lý biến đổi dữ liệu đầu vào và trả về kết quả.
Tài liệu hướng dẫn liên quan
- Tự phát triển một Plugin tùy biến — Hướng dẫn đưa các đoạn mã xử lý hook vào bộ khung plugin mới.
- Tự phát triển một Giao diện Theme — Hướng dẫn nhúng các head và footer action hooks vào tệp tin theme.
- Template Tags & Helpers — Danh sách các hàm bổ trợ hữu ích cho lập trình viên.
- Tổng quan kiến trúc hệ thống — Hiểu rõ hơn về vòng đời xử lý yêu cầu và các thời điểm kích hoạt hook.