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

Phân biệt action và filter trong hook WordPress qua ví dụ code

Vũ Đức Minh
Phân biệt action và filter trong hook WordPress qua ví dụ code
Cỡ chữ

Mỗi khi WordPress tải một trang, nó đi qua hàng trăm điểm dừng được đánh dấu sẵn. Tại mỗi điểm, lõi sẽ “gọi to” ra ngoài: ai có việc muốn làm ở đây không, ai muốn sửa dữ liệu này không. Cơ chế gọi đó chính là hook (điểm móc nối) — và hiểu nó là bước đầu để bạn viết được code WordPress thật sự.

Vì sao hook là xương sống của WordPress

WordPress được thiết kế để bạn không bao giờ sửa file lõi (core — mã nguồn gốc của WordPress). Lý do rất thực tế: hễ có bản cập nhật, mọi thay đổi trong lõi sẽ bị ghi đè, công sức tan biến. Hook giải quyết đúng vấn đề này. Thay vì sửa lõi, bạn đăng ký một hàm của mình vào một điểm móc nối có sẵn; khi WordPress chạy tới đó, hàm của bạn được gọi.

Toàn bộ hệ sinh thái plugin và theme đứng vững nhờ cơ chế này. Một plugin thêm nút chia sẻ vào cuối bài viết, một theme đổi đoạn chữ “Powered by” ở footer — tất cả đều móc vào hook, không động một dòng nào của lõi. Khi tự code plugin (như plugin web22-core mà Web22 dùng cho website của mình), gần như mọi tính năng đều bắt đầu bằng một dòng đăng ký hook.

Phân biệt hai loại hook action và filter trong WordPress
Action để chạy thêm việc; filter để sửa và trả lại dữ liệu.

Hai loại hook: action và filter

Đây là điểm dễ nhầm nhất với người mới, nên cần tách bạch ngay từ đầu. WordPress có đúng hai loại hook, và chúng phục vụ hai mục đích khác hẳn nhau.

Action — chạy một việc

Action (hành động) là điểm để bạn làm một việc gì đó: in ra màn hình, ghi vào cơ sở dữ liệu, gửi email, nạp một file script. Hàm móc vào action không cần trả về giá trị nào — nó chạy việc rồi thôi. WordPress phát ra một action bằng hàm do_action(); bạn móc vào bằng add_action().

Filter — sửa dữ liệu

Filter (bộ lọc) là điểm để bạn chỉnh sửa một dữ liệu rồi giao lại. Hàm móc vào filter bắt buộc phải nhận một giá trị vào và trả về một giá trị ra. Nếu bạn quên return, dữ liệu đó sẽ thành rỗng và trang dễ vỡ. WordPress phát ra một filter bằng apply_filters(); bạn móc vào bằng add_filter().

Một câu để nhớ: action làm việc và không trả về; filter biến đổi dữ liệu và phải trả về. Theo tài liệu chính thức của WordPress, filter còn nên hoạt động “biệt lập” — chỉ nhận vào, sửa, trả ra, tránh gây tác dụng phụ như đổi biến toàn cục hay tự in ra màn hình.

Cú pháp add_action và add_filter

Cả hai hàm có cùng dạng tham số, nên học một cái là hiểu cái còn lại:

add_action( $hook_name, $callback, $priority, $accepted_args );
add_filter( $hook_name, $callback, $priority, $accepted_args );
  • $hook_name — tên điểm móc nối bạn muốn gắn vào (ví dụ init, the_content).
  • $callback — tên hàm của bạn sẽ được gọi.
  • $priority — thứ tự ưu tiên, mặc định 10. Số càng nhỏ chạy càng sớm.
  • $accepted_args — số tham số mà hàm của bạn nhận, mặc định 1.

Hai tham số sau là tuỳ chọn. Hầu hết trường hợp đơn giản chỉ cần hai tham số đầu.

Ví dụ action — nạp file CSS riêng

Giả sử bạn muốn nạp một file CSS của theme. WordPress phát ra action wp_enqueue_scripts đúng vào lúc nên nạp tài nguyên ở giao diện. Bạn móc vào đó:

add_action( 'wp_enqueue_scripts', 'web22_nap_style' );

function web22_nap_style() {
    wp_enqueue_style(
        'web22-main',
        get_stylesheet_uri(),
        array(),
        '1.0'
    );
}

Hàm web22_nap_style() chỉ làm một việc — đăng ký file CSS — và không trả về gì. Đó là dấu hiệu kinh điển của một action. Đây cũng là cách chuẩn để nạp tài nguyên; nếu bạn còn mơ hồ chỗ này, bài cách nạp script và style đúng chuẩn trong WordPress đi sâu hơn.

Ví dụ filter — sửa nội dung bài viết

Bây giờ giả sử bạn muốn tự động thêm một dòng ghi chú vào cuối mọi bài viết. WordPress phát ra filter the_content với nội dung bài là dữ liệu đi qua. Bạn nhận nội dung đó, gắn thêm chữ, rồi trả về:

add_filter( 'the_content', 'web22_them_ghi_chu' );

function web22_them_ghi_chu( $content ) {
    if ( is_single() ) {
        $content .= '<p class="ghi-chu">Bài viết thuộc Web22.</p>';
    }
    return $content;
}

Khác biệt nằm ở chỗ: hàm nhận tham số $content và kết thúc bằng return $content. Nếu xoá dòng return, nội dung bài sẽ biến mất sạch — lỗi rất thường gặp khi mới làm quen với filter.

Priority — quyết định ai chạy trước

Khi nhiều hàm cùng móc vào một hook, $priority sắp thứ tự. Số nhỏ chạy trước, số lớn chạy sau. Mặc định là 10, nên nếu bạn cần một hàm chạy sau một plugin khác, hãy đặt số lớn hơn:

// Chạy muộn, sau các hàm priority 10
add_filter( 'the_content', 'web22_xu_ly_cuoi', 99 );

Khi hai hàm cùng priority, WordPress chạy theo đúng thứ tự chúng được đăng ký. Việc nắm priority rất hữu ích khi bạn phải “chen” vào sau một plugin đã sửa dữ liệu trước đó.

Accepted_args — nhận nhiều tham số

Một số hook truyền ra nhiều dữ liệu, không chỉ một. Mặc định callback chỉ nhận một tham số đầu; muốn lấy thêm, bạn phải khai báo rõ số lượng ở $accepted_args. Ví dụ filter comment_text truyền cả nội dung bình luận lẫn đối tượng bình luận:

add_filter( 'comment_text', 'web22_loc_binh_luan', 10, 2 );

function web22_loc_binh_luan( $text, $comment ) {
    // $comment giờ mới dùng được vì đã khai báo nhận 2 tham số
    return $text;
}

Quy tắc đơn giản: hàm của bạn cần đọc bao nhiêu tham số thì khai báo bấy nhiêu ở số cuối. Khai báo thiếu, các tham số sau sẽ rỗng.

Vai trò của priority và accepted_args khi gắn hook trong WordPress
Priority quyết định thứ tự chạy, accepted_args quyết định nhận mấy tham số.

Tự tạo hook trong code của bạn

Hook không chỉ để dùng — bạn cũng có thể tự phát ra hook riêng trong theme hay plugin, để người khác (hoặc chính bạn về sau) mở rộng mà không sửa code gốc:

// Trong template, phát ra một action riêng
do_action( 'web22_truoc_footer' );

// Phát ra một filter cho phép đổi tiêu đề
$tieu_de = apply_filters( 'web22_tieu_de_box', 'Mặc định' );

Đây chính là tư duy giúp code dễ bảo trì: thay vì viết cứng, bạn để ngỏ các điểm móc nối. Cách dùng hook bài bản còn liên quan chặt tới việc tổ chức file functions.php gọn gàng và an toàn, và là kiến thức cốt lõi khi làm theme tuỳ biến cho website.

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

Action và filter khác nhau ở điểm nào quan trọng nhất?

Action chạy một việc rồi không trả về gì; filter nhận dữ liệu, sửa rồi bắt buộc trả về. Quên return trong filter là lỗi phổ biến nhất.

Nên đặt code hook ở đâu?

Với theme, đặt trong functions.php; với tính năng độc lập, nên gói trong một plugin riêng để không mất khi đổi theme.

Làm sao biết một hook truyền ra bao nhiêu tham số?

Tra trang tài liệu của hook đó trên developer.wordpress.org, hoặc tìm dòng do_action() / apply_filters() tương ứng trong mã nguồn để đếm tham số.

Nắm vững hook là bước bản lề trước khi bạn đi xa hơn vào việc phát triển WordPress chuyên sâu. Nếu cần một website được code sạch và mở rộng đúng chuẩn hook ngay từ đầu, đội ngũ Web22 có thể đồng hành cùng bạn.

Đọc tiếp

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

Tất cả bài viết