21. Hướng dẫn sử dụng WordPress Transient API

Nhiệm vụ của Transient API sẽ hỗ trợ bạn tạo ra những dữ liệu tạm lưu sẵn ở trong hệ thống để giảm tải quá trình xử lý dữ liệu của hệ thống WordPress. Làm cho website của bạn chạy nhanh hơn. Nó tương tự như kỹ thuật caching trong php. Nó sẽ tạo ra một field và lưu dữ liệu đã cache vào table wp_options.

Để học tốt bài này thì bạn cần phải nắm vững cách tạo mới một Widget và biết cách sử dụng đối tượng WP_Query() để tương tác với database, nếu bạn có quên thì mời xem lại bài cũ trước rồi mới quay lại bài này, kẻo tẩu hỏa thì tôi không chịu trách nhiệm đâu đấy.

Trong bài Hướng dẫn sử dụng WordPress Transient API thì tôi sẽ đọc tài liệu và hướng dẫn lại cho bạn theo cách của tôi, và tôi chỉ sử dụng ba phương thức mà thôi , phần multisite tôi sẽ trình bày ở bài khác.

1/ Cấu trúc folder plugin kenshin transient

Tôi sẽ tạo một plugin mới để bạn dễ theo dõi và làm theo hơn là thay vì sử dụng lại cấu trúc của các plugin khác.

Cấu trúc plugin

kenshin-transient – widgets – includes – kenshin-transient.php (File xử lý chính của plugin)

Nội dung file kenshin-transient.php:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

<?php

/**

* @package Kenshin Transient API

* @version 0.1

*/

/*

Plugin Name: Kenshin Transient API

Plugin URI: http://laptrinhweb.org

Description: Đây là một plugin dùng để tương tác vói Transient API.

Author: Kenshin

Version: 0.1

Author URI: None

*/

define('KENSHIN_TRANSIENT_PLUGIN_URL', plugin_dir_url(__FILE__));

define('KENSHIN_TRANSIENT_PLUGIN_DIR', plugin_dir_path(__FILE__));

define('KENSHIN_TRANSIENT_INCLUDES_DIR', KENSHIN_TRANSIENT_PLUGIN_DIR .'/includes');

define('KENSHIN_TRANSIENT_DIR', KENSHIN_TRANSIENT_PLUGIN_DIR . '/widgets');

if(!is_admin()){

require_once KENSHIN_TRANSIENT_INCLUDES_DIR. '/frontend.php';

new KenshinFrontend();

}else{

require_once KENSHIN_TRANSIENT_INCLUDES_DIR. '/backend.php';

new KenshinBackend();

}

require_once KENSHIN_TRANSIENT_DIR. '/last-post.php';

new Kenshin_Widget_Last_Post();

add_action('widgets_init', 'ks_widget_register_last_post');

function ks_widget_register_last_post(){

register_widget('Kenshin_Widget_Last_Post');

}

Kế tiếp tôi vào folder widgets tạo file last-post.php đây chính là file xử lý chính của Widget.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<?php

class Kenshin_Widget_Last_Post extends WP_Widget {

public function __construct() {

$id_base = 'kenshin-widget-last-post';

$name = 'Kenshin Last Post';

$widget_options = array(

'classname' => 'kenshin-wg-css-last-post',

'description' => 'Đây là Last Post'

);

parent::__construct($id_base, $name, $widget_options);

}

public function widget( $args, $instance ) {

}

public function update( $new_instance, $old_instance ) {

return $instance;

}

public function form( $instance ) {

}

}

Đây là kiến thức cũ nên tôi sẽ không mất công để giải thích lại. Bạn vào vùng quản lý Widget theo đường dẫn http://localhost/wp/wp-admin/widgets.php.

Hướng dẫn sử dụng WordPress Transient API

widget-last-post

À, nội dung trong bài thì tôi sẽ hướng dẫn bạn xây dựng một Widget có tên là Last Post, tức là hiển thị danh sách bài viết theo số lượng.

Xây dựng Form Widget Last Post:

Chúng ta sẽ phải tạo ra 2 ô textbox như sau.

Hướng dẫn sử dụng WordPress Transient API

widget-last-post-form

Tôi có đoạn code xử lý, vì do phần tạo form tôi đã hướng dẫn rồi nên tôi sẽ không nhắc lại nửa.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

public function form( $instance ) {

// Phần từ Form title

$inputID = $this->get_field_id('title');

$inputName = $this->get_field_name('title');

$inputValue = $instance['title'];

echo '<p>';

echo '<label>Title:</label>';

echo '<input type="text" class="widefat" id="'.$inputID.'" name="'.$inputName.'" value="'.$inputValue.'" />';

echo '</p>';

// Phần từ Form Items

$inputID = $this->get_field_id('items');

$inputName = $this->get_field_name('items');

$inputValue = $instance['items'];

echo '<p>';

echo '<label>Number Of Post:</label>';

echo '<input type="text" class="widefat" id="'.$inputID.'" name="'.$inputName.'" value="'.$inputValue.'" />';

echo '</p>';

}

Kế tiếp tôi sẽ đưa dữ liệu vào table , bạn nhập cái giá trị vào form như hình trên rồi bấm save rồi sau đó vào phpmyadmin tìm đến table wp_options xem có field nào tên là widget_kenshin-widget-last-post, nếu có thì xem như thành công.

1

2

3

4

5

6

7

8

9

10

public function update( $new_instance, $old_instance ) {

// Gán giá trị hiện tại bằng với giá trị cũ

$instance = $old_instance;

// Mảng giá trị hiện tại bằng với giá trị insert vào csdl

$instance['title'] = strip_tags($new_instance['title']);

$instance['items'] = strip_tags($new_instance['items']);

return $instance;

}

Phần tạo form xem như tạm ổn rồi đấy, kế tiếp tôi sẽ xử lý Widget hiển thị ngoài trang chủ, và do tôi đang dùng themes Twenty Thrỉdteen nên tôi sẽ kéo Widget sang vùng Sidebar 2 tức là Secondary Widget Area.

Tôi sẽ biến ác phần tử mảng toàn bộ thành biến bằng hàm extract(), sau đó vẫn giống như các bài trước tôi sẽ kiểm tra nếu các biến không tồn tại thì sẽ gán cho nó một giá trị mặc định để không phát sinh ra lỗi.

1

2

3

4

5

6

7

8

public function widget( $args, $instance ) {

extract($args);

$title = apply_filters('widget_title', $instance['title']);

$title = (empty($title)) ? 'Abc Last Post' : $title;

$items = (empty($instance['items'])) ? '5' : $instance['items'];

}

Lúc này tôi sẽ sử dụng tới đối tượng WP_Query() để lấy ra danh sách các bài viết.

1

2

3

4

5

6

7

8

9

// Mảng chứa các phần tử trong WP_Post (Biến toàn cục $wpdb)

$args = array(

'post_type' => 'post', // Kiểu bài viết phải là post

'post_status' => 'publish', // status publish mới hiển thị bài viết

'posts_per_page' => $items, // Số bài trên một trang

);

$wpQuery = new WP_Query($args);

Khởi tạo một mảng chứa các phần tử trong WP_post tức là đại diện cho biến toàn cục $wpdb đó bạn, post_type là kiểu bài viết, WordPress có 2 mặc định hai kiểu là post & page, ở bài này tôi chỉ muốn lấy ra danh sách các bài viết thuộc dạng post mà thôi nên tôi sẽ gán giá trị cho phần tử là post.

Và chỉ có những bài viết ở trạng thái publish tôi mới hiển thị ra ngoài trang chủ, ngoài ra phần tửposts_per_page chính là số bài viết trên một trang, nó sẽ được gán bằng với giá trị của biến $items.

Để lấy được danh sách các bài viết thì bạn cần dùng tới thằng The Loop (Vòng lặp).

1

2

3

4

5

6

7

8

9

10

11

12

if ($wpQuery->have_posts()){

echo '<ul>';

while($wpQuery->have_posts()){

$wpQuery->the_post();

// Phần tử guid chính là field chứa link bài viết được lưu trong table wp_post

$link = $wpQuery->post->guid;

echo '<li><a href='. $link .'>'. get_the_title(). '</a></li>';

}

echo '</ul>';

// Giải phóng bộ nhớ của database khi sử dụng đối tượng WP_Query

wp_reset_postdata();

}

Tôi có chú thích rõ trong code, nếu bạn không hiểu thì có thể bình luận dưới bài viết tôi và các tác giả khác sẽ giải đáp cho bạn.

Nội dung file last-post.php:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

<?php

class Kenshin_Widget_Last_Post extends WP_Widget {

private $_caching_name = 'kenshin_wg_last_post_caching';

public function __construct() {

$id_base = 'kenshin-widget-last-post';

$name = 'Kenshin Last Post';

$widget_options = array(

'classname' => 'kenshin-wg-css-last-post',

'description' => 'Đây là Last Post'

);

parent::__construct($id_base, $name, $widget_options);

}

public function widget( $args, $instance ) {

extract($args);

$title = apply_filters('widget_title', $instance['title']);

$title = (empty($title)) ? 'Abc Last Post' : $title;

$items = (empty($instance['items'])) ? '5' : $instance['items'];

// Mảng chứa các phần tử trong WP_Post (Biến toàn cục $wpdb)

$args = array(

'post_type' => 'post', // Kiểu bài viết phải là post

'post_status' => 'publish', // status publish mới hiển thị bài viết

'posts_per_page' => $items, // Số bài trên một trang

);

$wpQuery = new WP_Query($args);

if ($wpQuery->have_posts()){

echo '<ul>';

while($wpQuery->have_posts()){

$wpQuery->the_post();

// Phần tử guid chính là field chứa link bài viết được lưu trong table wp_post

$link = $wpQuery->post->guid;

echo '<li><a href='. $link .'>'. get_the_title(). '</a></li>';

}

echo '</ul>';

// Giải phóng bộ nhớ của database khi sử dụng đối tượng WP_Query

wp_reset_postdata();

}

}

public function update( $new_instance, $old_instance ) {

// Gán giá trị hiện tại bằng với giá trị cũ

$instance = $old_instance;

// Mảng giá trị hiện tại bằng với giá trị insert vào csdl

$instance['title'] = strip_tags($new_instance['title']);

$instance['items'] = strip_tags($new_instance['items']);

return $instance;

}

public function form( $instance ) {

// Phần từ Form title

$inputID = $this->get_field_id('title');

$inputName = $this->get_field_name('title');

$inputValue = $instance['title'];

echo '<p>';

echo '<label>Title:</label>';

echo '<input type="text" class="widefat" id="'.$inputID.'" name="'.$inputName.'" value="'.$inputValue.'" />';

echo '</p>';

// Phần từ Form Items

$inputID = $this->get_field_id('items');

$inputName = $this->get_field_name('items');

$inputValue = $instance['items'];

echo '<p>';

echo '<label>Number Of Post:</label>';

echo '<input type="text" class="widefat" id="'.$inputID.'" name="'.$inputName.'" value="'.$inputValue.'" />';

echo '</p>';

}

}

2/ Sử dụng Transient API cache Widget Last Post

Transient API có tổng cộng là 6 phương thức nhưng trong bài tôi chỉ hướng dẫn bạn sử dụng 3 phương thức mà thôi, đầu tiên là phương thức khởi tạo Cache.

set_transient(): Nó có ba tham số tất cả, đầu tiên là tên lưu vào csdl, tham số thứ hai là dữ liệu cần cache, tham số thứ ba là thời gian cache hoạt động.

1

set_transient( $transient, $value, $expiration );

get_transient(): Nó có duy nhất một tham số là tên lưu vào csdl và 2 điều kiện nếu false thì không sử dụng cache, true thì sử dụng cache.

1

get_transient( $transient );

delete_transient(): Nó cũng chỉ có duy nhất một tham số truyền vào tên cache và thực hiện xóa cache.

1

delete_transient( $transient );

Đầu tiên tôi sẽ tạo ra biến toàn cục $_caching_name để gán giá trị tên cache lưu vào table wp_options là kenshin_wg_last_post_caching. Tôi sẽ xử lý phần cache ngay tại phương thức Widget() như sau.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

public function widget( $args, $instance ) {

extract($args);

$title = apply_filters('widget_title', $instance['title']);

$title = (empty($title)) ? 'Abc Last Post' : $title;

$items = (empty($instance['items'])) ? '5' : $instance['items'];

// Caching sẽ trả về hai giá trị true hoặc false

$caching = get_transient($this->_caching_name);

if ($caching == false){

echo '<br /> Không sử dụng cache';

// Mảng chứa các phần tử trong WP_Post (Biến toàn cục $wpdb)

$args = array(

'post_type' => 'post', // Kiểu bài viết phải là post

'post_status' => 'publish', // status publish mới hiển thị bài viết

'posts_per_page' => $items, // Số bài trên một trang

);

$wpQuery = new WP_Query($args);

// Tham số đầu tiên là tên caching lưu vào table wp_options

// Tham số thứ hai là dữ liệu cần cache

// Tham số thứ ba lả thời gian thực hiện việc caching

set_transient($this->_caching_name, $wpQuery, 3 * MINUTE_IN_SECONDS);

} else {

$wpQuery = $caching;

echo '<br /> Sử dụng cache';

}

if ($wpQuery->have_posts()){

echo '<ul>';

while($wpQuery->have_posts()){

$wpQuery->the_post();

// Phần tử guid chính là field chứa link bài viết được lưu trong table wp_post

$link = $wpQuery->post->guid;

echo '<li><a href='. $link .'>'. get_the_title(). '</a></li>';

}

echo '</ul>';

// Giải phóng bộ nhớ của database khi sử dụng đối tượng WP_Query

wp_reset_postdata();

}

}

Nếu $caching bằng false thì sẽ lưu dữ liệu vào database, ngược lại sẽ tiến hành cache, bạn vào phpmyadmin kiểm tra tại table wp_options nếu phát sinh ra 2 field _transient_timeout_kenshin_wg_last_post_caching _transient_kenshin_wg_last_post_caching, thì xem như quá trình cache đã diễn ra.

Lúc này tôi muốn mỗi khi cập nhật dữ liệu mới từ form thì sẽ tự xóa đi cache cũ và cập nhật cache mới thì phải làm sao? Ngay tại phương thức update() tôi xử lý bằng cách thêm phương thức delete_transient() vào.

1

2

3

4

5

6

7

8

9

10

11

12

13

public function update( $new_instance, $old_instance ) {

// Gán giá trị hiện tại bằng với giá trị cũ

$instance = $old_instance;

// Mảng giá trị hiện tại bằng với giá trị insert vào csdl

$instance['title'] = strip_tags($new_instance['title']);

$instance['items'] = strip_tags($new_instance['items']);

// Xóa cache mỗi khi cập nhật dữ liệu mới

delete_transient($this->_caching_name);

return $instance;

}

Full code file last-post.php:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

<?php

class Kenshin_Widget_Last_Post extends WP_Widget {

private $_caching_name = 'kenshin_wg_last_post_caching';

public function __construct() {

$id_base = 'kenshin-widget-last-post';

$name = 'Kenshin Last Post';

$widget_options = array(

'classname' => 'kenshin-wg-css-last-post',

'description' => 'Đây là Last Post'

);

parent::__construct($id_base, $name, $widget_options);

}

public function widget( $args, $instance ) {

extract($args);

$title = apply_filters('widget_title', $instance['title']);

$title = (empty($title)) ? 'Abc Last Post' : $title;

$items = (empty($instance['items'])) ? '5' : $instance['items'];

// Caching sẽ trả về hai giá trị true hoặc false

$caching = get_transient($this->_caching_name);

if ($caching == false){

echo '<br /> Không sử dụng cache';

// Mảng chứa các phần tử trong WP_Post (Biến toàn cục $wpdb)

$args = array(

'post_type' => 'post', // Kiểu bài viết phải là post

'post_status' => 'publish', // status publish mới hiển thị bài viết

'posts_per_page' => $items, // Số bài trên một trang

);

$wpQuery = new WP_Query($args);

// Tham số đầu tiên là tên caching lưu vào table wp_options

// Tham số thứ hai là dữ liệu cần cache

// Tham số thứ ba lả thời gian thực hiện việc caching

set_transient($this->_caching_name, $wpQuery, 3 * MINUTE_IN_SECONDS);

} else {

$wpQuery = $caching;

echo '<br /> Sử dụng cache';

}

if ($wpQuery->have_posts()){

echo '<ul>';

while($wpQuery->have_posts()){

$wpQuery->the_post();

// Phần tử guid chính là field chứa link bài viết được lưu trong table wp_post

$link = $wpQuery->post->guid;

echo '<li><a href='. $link .'>'. get_the_title(). '</a></li>';

}

echo '</ul>';

// Giải phóng bộ nhớ của database khi sử dụng đối tượng WP_Query

wp_reset_postdata();

}

}

public function update( $new_instance, $old_instance ) {

// Gán giá trị hiện tại bằng với giá trị cũ

$instance = $old_instance;

// Mảng giá trị hiện tại bằng với giá trị insert vào csdl

$instance['title'] = strip_tags($new_instance['title']);

$instance['items'] = strip_tags($new_instance['items']);

// Xóa cache mỗi khi cập nhật dữ liệu mới

delete_transient($this->_caching_name);

return $instance;

}

public function form( $instance ) {

// Phần từ Form title

$inputID = $this->get_field_id('title');

$inputName = $this->get_field_name('title');

$inputValue = $instance['title'];

echo '<p>';

echo '<label>Title:</label>';

echo '<input type="text" class="widefat" id="'.$inputID.'" name="'.$inputName.'" value="'.$inputValue.'" />';

echo '</p>';

// Phần từ Form Items

$inputID = $this->get_field_id('items');

$inputName = $this->get_field_name('items');

$inputValue = $instance['items'];

echo '<p>';

echo '<label>Number Of Post:</label>';

echo '<input type="text" class="widefat" id="'.$inputID.'" name="'.$inputName.'" value="'.$inputValue.'" />';

echo '</p>';

}

}

3/ Lời kết

Hy vọng thông qua bài Hướng dẫn sử dụng WordPress Transient API thì bạn sẽ phần nào biết thêm kiến thức về caching để giúp website của bạn được tối ưu hơn, đây chỉ là một ví dụ nhỏ về cách sử dụng Transient API, chứ nó chưa thật sự là một giải pháp tốt nhất đâu đấy.

Series Navigation<< Tìm hiểu đối tượng WP_Query trong WordPressSử dụng WordPress The Loop >>

Nguồn: laptrinhweb.org

Last updated