WordPress Hooks là gì ? làm sao để trở thành master ?

action filter

Khi lập trình với WordPress chúng ta thường nghe nói tới hooks, vậy câu hỏi đặt ra là:  hooks là gì và cách sử dụng chúng như thế nào? Trong bài viết này WCT sẽ cùng các bạn tìm hiểu về nó, về cách hoạt động, sức mạnh của nó trong việc phát triển plugins, themes WordPress.

Hooks trong WordPress là gì ?

Hooks ở đây nghĩa là những cái móc, chúng được đặt sẵn trong core của WordPress. Những cái móc này sẽ là nơi để bạn “móc” các hàm hay phương thức( nếu bạn sử dụng lập trình hướng đối tượng, ở đây tôi sẽ chủ yếu dùng hàm ) của mình vào mà không phải sửa đổi mã nguồn WordPress. Việc sử dụng đúng các hooks sẽ giúp việc tùy biến mã nguồn WordPress trở nên dễ dàng theo ý muốn của các developer.

WordPress có 2 nhóm hooks chính là action hooks và filter hook. Mỗi nhóm hooks có tác dụng riêng

  • Action hooks: là các hooks liên quan tới việc xử lý hành động
  • Filter hooks: là các hooks liên quan tới việc lọc nội dung

Để xem danh sách các hooks mặc định của WordPress bạn có thể vào  link sau: http://adambrown.info/p/wp_hooks/hook

Chúng ta sẽ cùng nhau làm rõ hơn cách sử dụng từng loại hooks trong phần tiếp theo.

Action hooks

Trong WordPress, action là một hàm PHP được chạy tại một vị trí “móc” đặc biệt của core WordPress. Các action hooks giúp chúng ta có thể tùy biến WordPress mà không phải sửa trực tiếp trong core WordPress .

Thêm một action với hàm add_action()

WordPress cung cấp hàm add_action để chúng ta có thể thêm một một action  vào action hook. Hàm này có dạng sau:

<?php
add_action( $tag, $function_to_add, $priority = 10, $accepted_args = 1 );

Trong đó:

  • $tag: là tên của action hook
  • $function_to_add là hàm callback chúng ta muốn thêm vào $tag
  • $priority là mức độ ưu tiên của hàm callback, giá trị của $priority càng thấp thì nó sẽ được gọi càng sớm. Giá trị mặc định là 10.
  • $accepted_args là tổng số các tham số của hàm callback. Giá trị mặc định là 1

Chúng ta sẽ cùng làm một ví dụ để hiểu rõ hơn về action hooks:

Bạn hãy thêm đoạn code sau vào file: functions.php trong theme của mình và chạy lại site để xem kết quả

<?php
add_action( wp_footer, wptq_copyright, 100 );
function wptq_copyright() {
echo <p class=”copyright”>&copy; WCT .date(Y).. All Right reserved</p>;
}

Bạn có thể tham khảo thêm danh sách các action hook mặc định của WordPress tại địa chỉ sau: https://codex.wordpress.org/Plugin_API/Action_Reference

Gỡ một action với remove_action()

Chúng ta sử dụng hàm remove_action() để loại bỏ một action tại một hook. Cú pháp của nó như sau:

<?php
remove_action( $tag, $function_to_remove, $priority );

Trong đó:

  • $tag: là tên của action hook
  • $function_to_remove là tên hàm sẽ bị loại bỏ khỏi hook $tag
  • $priority là mức độ ưu tiên của hàm callback, nó được định nghĩa khi được hook vào $tag. Giá trị mặc định là 10.

Như ví dụ phần hàm add_action tôi có thêm hàm wptq_copyright() vào hook wp_footer, bây giờ tôi có thể bỏ nó khỏi hook wp_footer một cách đơn giản như sau:

<?php
remove_action( wp_footer, wptq_copyright, 100 );

Thực thi một action với do_action()

Trong quá trình phát triển theme, plugin WordPress chúng ta thường xuyên có nhu cầu tạo ra các hook riêng để dễ dàng tùy chỉnh về sau. Vậy làm thế nào để có thể tạo một action hook riêng, WordPress cung cấp hàm do_action để giải quyết vấn đề đó. Hàm này có dạng như sau

<?php
do_action( $tag, $arg = );
view rawwp_do_action.php hosted with ❤ by GitHub

Trong đó:

  • $tag: là tên action hook riêng của chúng ta
  • $arg là các tham số sẽ được truyền vào cho các hàm được “móc” vào action hook $tag

Để hiểu hơn về hàm này, chúng ta sẽ cùng nhau làm một ví dụ đơn giản, trong theme của mình tôi sẽ tạo thư mục templates chứa file full-width.php, nội dung file templates/full-width.php sẽ như sau:

<?php
/**
* Template Name: Full Width
*/
?>
<?php get_header(); ?>
<div class=wrap>
<?php do_action( wptq_before_content ); ?>
<div id=primary class=content-area>
<main id=main class=site-main role=main>
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_content();
endwhile;
endif;
?>
</main>
</div>
</div>
<?php get_footer(); ?>
view rawfull-width.php hosted with ❤ by GitHub

Các bạn hãy chú ý vào dòng số 8, tôi có đoạn: do_action( ‘wptq_before_content’ ),  ở đây chúng ta sẽ tạo một action hook riêng có tên là wptq_before_content,  lúc này chúng ta có thể sử dụng hook wptq_before_content giống như cách sử dụng action hook mặc định của WordPress. Ví dụ như sau, tôi sẽ viết một hàm đơn giản hiển thị tiêu đề bài viết:

add_action( ‘wptq_before_content’, ‘wptq_page_title’ );
function wptq_page_title(){
if ( is_home() && ! is_front_page() ){
?>
<header class=page-header>
<h1 class=page-title><?php single_post_title(); ?></h1>
</header>
<?php
}
}

Ở đây tôi sẽ gắn hàm wptq_page_title() vào action hook wptq_before_content  mà chúng ta tự tạo trong file: templates/full-width.php

Cách làm này thường được dùng trong các theme framework để dễ dàng tùy biến theme cho phù hợp với mục đích của developer. Nếu bạn làm việc với các template của Woocommerce, bạn sẽ thấy các template của họ sử dụng rất nhiều các action hook tự tạo, khi đó việc tùy chỉnh các template trở nên thật dễ dàng.

Filter hooks

Filter ở đây nghĩa là “lọc”, filter hooks sẽ làm nhiệm vụ lọc dữ liệu trong hệ thống WordPress. Chúng ta sẽ sử dụng filter hooks để lọc dữ liệu trước khi được hiển thị ra bên ngoài mà không làm thay đổi dữ liệu gốc được lưu trong cơ sở dữ liệu. Cũng giống như action hook, WordPress cũng cung cấp cho chúng ta các hàm để làm việc với filter hook

Thêm một filter với add_filter()

Chúng ta sử dụng hàm add_filter để thêm một hàm vào một filter hook. Hàm này có dạng như sau:

<?php
add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 );
view rawadd_filter_wp.php hosted with ❤ by GitHub

Trong đó:

  • $tag: là tên của filter hook
  • $function_to_add là hàm callback chúng ta muốn thêm vào $tag
  • $priority là mức độ ưu tiên của hàm callback, giá trị của $priority càng thấp thì nó sẽ được gọi càng sớm. Giá trị mặc định là 10.
  • $accepted_args là tổng số các tham số của hàm callback. Giá trị mặc định là 1

Bạn có thể thấy các tham số của nó tương tự như các tham số của hàm add_action. Chúng ta sẽ cùng làm một ví dụ để hiểu rõ hơn về nó.

<?php
add_filter( the_title, wptq_strong_title );
function wptq_strong_title( $title ){
return <strong> . $title . </strong>;
}

Ở ví dụ này, tôi sử dụng filter hook the_title để thay đổi cấu trúc tiêu đề bài viết. Hàm wptq_strong_title sẽ làm nhiệm vụ lọc, thay đổi tiêu đề trước khi nó được hiển thị ra ngoài.

Bạn có thể tham khảo danh sách các filter hook có sẵ của WordPress tại địa chỉ sau: https://codex.wordpress.org/Plugin_API/Filter_Reference

Gỡ bỏ một action với remove_fitler()

Hàm remove_filter được dùng để loại bỏ một hàm đã được gán vào một filter hook, nó có dạng như sau:

<?php
remove_filter( $tag, $function_to_remove, $priority );
view rawremove_filter.php hosted with ❤ by GitHub

Trong đó:

  • $tag: là tên của filter hook
  • $function_to_remove là tên hàm sẽ bị loại bỏ khỏi hook $tag
  • $priority là mức độ ưu tiên của hàm callback, nó được định nghĩa khi được hook vào $tag. Giá trị mặc định là 10.

Khi ví dụ về hàm add_filter, tôi có gán hàm wptq_strong_title vào hook the_title, bây giờ chúng ta có thể loại bỏ nó khỏi hook một cách đơn giản như sau:

<?php
remove_filter( the_title, wptq_strong_title );

Thực thi filter với apply_filters()

Cũng giống như action hook, WordPress cũng cho phép chúng ta tự tạo filter hook thông qua hàm apply_fitlers. Nó có dạng như sau:

<?php
apply_filters( $tag, $value, $var );
view rawapply_filter_wp.php hosted with ❤ by GitHub

Trong đó:

  • $tag: là tên của filter hook
  • $value là giá trị của filter hook $tag 
  • $var là các biến được truyền vào cho các hàm được móc vào filter hook $tag này.

Chúng ta sẽ cùng nhau làm một ví dụ với hàm này, ở đây tôi sửa lại file footer.php  trong theme của mình thành dạng sau

view rawfooter.php hosted with ❤ by GitHub

Bạn chỉ cần quan tâm tới dòng số 10, ở đây tôi tự tạo một filter hook có tên là wptq_copyright. Bây giờ tôi có thể dễ dàng thay đổi lại phần copyright này như sau:

<?php
add_filter( wptq_copyright, wptq_modify_copyright );
function wptq_modify_copyright(){
return <p>Proudly powered by WordPress – WCT</p>;
}

Cách dùng thật đơn giản, bạn có thể chạy thử để xem nội dung copyright đã được thay đổi ra sao.

Làm sao để biết các hàm( hoặc phương thức ) nào đã được “móc” vào một hook cụ thể?

Trong quá trình phát triển themes, plugins có đôi lúc chúng ta thường thêm hoặc loại bỏ các hàm khỏi một hook đã có sẵn. Nhiều khi chúng ta cần biết được hàm nào ( hoặc phương thức nào ) đã được “móc” vào hook đó. WordPress sử dụng biến global $wp_filter để lưu thông tin về các action đã được thêm vào các hook, tôi có một hàm đơn giản để lấy thông tin về các hàm( hoặc phương thức ) đã được gán vào một hook cụ thể

<?php
function wptq_hooked_action_for( $hook_name = ){
global $wp_filter;
if( empty( $hook_name ) || !isset( $wp_filter[$hook_name] ) || !is_object( $wp_filter[$hook_name] ) ){
return;
}
$list_hooked = array();
$callbacks = $wp_filter[$hook_name]->callbacks;
if( !empty( $callbacks ) ){
foreach( $callbacks as $key=>$value ){
if( is_array( $value ) && !empty( $value ) ){
foreach( $value as $k=>$v ){
if( array_key_exists( function, $v ) && !is_array( $v[function] ) ){
$list_hooked[] = array(
type => function,
function_name => $v[function],
accepted_args => $v[accepted_args],
priority => $key
);
}elseif( array_key_exists( function, $v ) && is_array( $v[function] ) && is_object( $v[function][0] ) && !empty( $v[function][1] ) ){
$list_hooked[] = array(
type => method,
object_name => get_class( $v[function][0]),
method_name => $v[function][1],
accepted_args => $v[accepted_args],
priority => $key
);
}
}
}
}
}
echo <pre>;
print_r( $list_hooked );
echo </pre>;
}
//Example
wptq_hooked_action_for( wp_head );
view rawget_list_hooked.php hosted with ❤ by GitHub

Khi bạn chạy thử hàm trên, nó sẽ trả lại cho chúng ta một mảng đa chiều chứa thông tin của các hàm (hoặc phương thức) đã được gán vào hook đó, nó sẽ thật tiện cho việc phát triển, tùy biến themes, plugins của bạn.

Tóm lại

việc sử dụng thành thạo action hooks và filter hooks trong WordPress sẽ giúp chúng ta dễ dàng tùy biến WordPress cho phù hợp với yêu cầu của mình.

WCT xin được dừng bài viết tại đây, vui lòng để lại comment cho chúng tôi nếu bạn có bất kì góp ý hay thắc mắc gì.

0938.54.84.99