Actions và Filter Hooks là gì?
Actions là một trong 2 loại Hooks, chúng cung cấp cách để chạy hàm tại một số điểm neo trong quá trình chạy cách hàm thuộc WordPress Core, plugins và themes. Các hàm này thì trái ngược với filter hook là chạy được liền mạch và không làm thay đổi các giá trị như filter hook.
function wporg_callback() {
// do something
}
add_action( 'init', 'wporg_callback' );Một ví dụ về init hook, thực tế chi tiết của Actions hook thì series của anh Thạch Phạm đã nêu khá rõ rồi, Nam sẽ lướt qua để đỡ mất thời gian
Đây là một ví dụ khá hay và phù hợp với việc phát triển WordPress, hình dung bạn muốn gỡ một function nặng (như slider chẳng hạn) vì giao diện hiện tại không dùng đến, lúc này bạn sẽ sử dụng hàm
function wporg_disable_slider() {
// Make sure all parameters match the add_action() call exactly.
remove_action( 'template_redirect', 'wporg_setup_slider', 9 );
}
// Make sure we call remove_action() after add_action() has been called.
add_action( 'after_setup_theme', 'wporg_disable_slider' );Việc gỡ bỏ các hàm không cần thiết sẽ giúp cho hiệu năng Website WordPress của bạn trở nên tối ưu hơn.
function wporg_modify_content( $content ) {
switch ( current_filter() ) {
case 'the_content':
// Do something.
break;
case 'the_excerpt':
// Do something.
break;
}
return $content;
}
add_filter( 'the_content', 'wporg_modify_content' );
add_filter( 'the_excerpt', 'wporg_modify_content' );Khi chạy add_filter vào 2 hàm the_content và the_excerpt (Nội dung và tóm tắt bài viết), bạn có thể dùng hàm current_filter() để trả về hooks hiện hành và thực hiện các thay đổi theo điều kiện mong muốn.
function wporg_custom() {
// If save_post has been run more than once, skip the rest of the code.
if ( did_action( 'save_post' ) !== 1 ) {
return;
}
// ...
}
add_action( 'save_post', 'wporg_custom' );Đây là đoạn mã khá hay với đoạn did_action(‘tên hook’), bạn có thể giới hạn số lần hook này chạy.
Để thực hiện việc này chúng ta sử dụng hàm do_action và apply_filters, trong đó do_action là để tạo action hook mới còn apply_filters để tạo filters hook mới (Sẽ được tin dùng nhất khi in các dữ liệu ra trình duyệt)
Giả dụ trong 1 file nào đó của plugin, bạn muốn bổ sung vị trí action hook nhằm chèn một thông báo chẳng hạn, lúc này bạn dùng hàm
do_action( 'wporg_after_settings_page_html' );Lúc này bạn có thể dễ dàng đẩy vào callback function mong muốn
add_action( 'wporg_after_settings_page_html', 'myprefix_add_settings' );
function myprefix_add_settings() {
echo "Xin chào";
}function wporg_create_post_type() {
$post_type_params = [/* ... */];
register_post_type(
'post_type_slug',
apply_filters( 'wporg_post_type_params', $post_type_params )
);
}Trong quá trình đăng ký post type sẽ tạo 1 filters hook tên là ‘wporg_post_type_params’, lưu ý là filter hook có đặc tính như sau
Note that filters filters take data, modify it, and return it.
Tức là lúc này filters wporg_post_type_params sẽ trả về giá trị mong muốn vào biến $post_type_params (tham số của custom post type)
function myprefix_change_post_type_params( $post_type_params ) {
$post_type_params['hierarchical'] = true;
return $post_type_params;
}
add_filter( 'wporg_post_type_params', 'myprefix_change_post_type_params' );Sau khi chạy hàm myprefix_change_post_type_params, $post_type_params sẽ được trả về khi kết thúc hàm wporg_post_type_params
Filters are one of the two types of Hooks. They provide a way for functions to modify data during the execution of WordPress Core, plugins, and themes. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. Filters expect to have something returned back to them.
Như vậy filters sẽ lấy dữ liệu, xử lý và trả về ngay trong quá trình chạy của WordPress Core, plugins và themes.
function wporg_filter_title( $title ) {
return 'The ' . $title . ' was filtered';
}
add_filter( 'the_title', 'wporg_filter_title' );Đây là ví dụ của hàm wporg_filter_title($title), ngoài ra, ta có thể bổ sung các biến và tham số vào các thành phần có sẵn của WordPress
function wporg_css_body_class( $classes ) {
if ( ! is_admin() ) {
$classes[] = 'wporg-is-awesome';
}
return $classes;
}
add_filter( 'body_class', 'wporg_css_body_class' );Như ở ví dụ trên thì ta đã ghép vào hook body_class một phần tử là wporg-is-awesome, nhưng chỉ dành riêng cho người đăng nhập thôi
Như rất nhiều WordPress plugins khác, Woocommerce cung cấp rất nhiều hook để người dùng có thể phát triển và mở rộng nền tảng.
Việc sử dụng lại các hook có sẵn luôn được khuyến khích, nếu tạo mới hook, bạn cần có sự suy nghĩ về lâu dài.
Hẳn bạn sẽ không còn xa lạ với cách thức phát triển WordPress sử dụng các action hook để làm giàu nội dung cho các vị trí có sẵn, ví dụ trong màn sản phẩm chi tiết, bạn muốn đẩy một cái banner giảm giá vào hook woocommerce_single_product_summary chẳng hạn, lúc này bạn chỉ cần chèn 1 hàm call back vào action hook đó
Một số vị trí mà Lifecycle hook thường hiện diện đó là:
Về mặt đặc tính, lifecycle hooks
Dưới đây là một ví dụ của Lifecycle hook khi nó đặt trong 1 hàm hiển thị khuyến mại
function woocommerce_get_current_promotions( ...$args ) {
/* Any initial prep, then first lifecycle hook... */
do_action( 'woocommerce_before_get_current_promotions', $args );
/* ...Do actual work, then final lifecycle hook... */
do_action( 'woocommerce_after_get_current_promotions', $result, $args );
/* ...Return the result, optionally via a filter... */
return apply_filters( 'woocommerce_get_current_promotions', $result, $args );
}
Ta thấy chúng trả về 2 hooks
Trong đó hàm after trả về cả một biến kết quả cùng tham số $result và $args.
The ‘before’ hook will generally always provide callbacks with the arguments array, if there is one The ‘after’ hook will generally also provide callbacks with the function’s return value, if there is one
Woocommerce Developer Handbook
Escape hook là việc để cho hàm dừng xử lý ngay tại thời điểm đó, khi mà bạn đã chắc chắn mình chỉ cần những tính năng như vậy thôi.
function get_product_metrics( $args ): array {
$pre = apply_filters( 'pre_woocommerce_get_product_metrics', null, $args );
if ( $pre !== null ) {
return (array) $pre;
}
/* ...Default logic... */
return $metrics;
}