32. Sử dụng WordPress Custom Post Type nâng cao

Custom Post là một kiểu định dạng bài viết khác với hai kiểu mặc định Post & Page trong hệ thống WordPress, ở bài Sử dụng WordPress Custom Post Type căn bản, thì tôi đã hướng dẫn bạn cách khai báo và tạo mới một Custom Post cũng như giới thiệu một số tham số hỗ trợ trong phương thức register_post_type(). Và nội dung trong bài Sử dụng WordPress Custom Post Type nâng caothì tôi sẽ hướng dẫn bạn kết hợp với WordPress Metaboxes để tạo ra bài viết với kiểu định dạng là Product.

Để nắm rõ cốt lõi toàn bộ vấn đề trong bài thì bạn cần phải đạt được nền tảng kiến thức với các bài sau đây.

· Tìm hiểu WordPress Metaboxes

· Tương tác database với WordPress Metaboxes

· Bảo mật và tối ưu WordPress Metaboxes

· Hiển thị WordPress Metaboxes ngoài trang chủ

Tôi sẽ thay đổi cấu trúc plugin một tí, có nghĩa là plugin sẽ bao gồm phần Custom Post & Metaboxes luôn chứ không riêng lẽ nửa.

1/ Cấu trúc plugin nâng cao

Nói nâng cao cho nó sang vậy thôi, chứ tôi sẽ copy 2 folder metaboxes & posts từ các bài mà tôi đã đề cập ở trên sang, và đây là cấu trúc plugin của tôi.

Sử dụng WordPress Custom Post Type nâng cao

cau-truc-myplugin

Nội dung file myplugin.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

<?php

/**

* @package Kenshin My Plugin

* @version 0.1

*/

/*

Plugin Name: Kenshin My Plugin

Plugin URI: http://laptrinhweb.org

Description: Đây là một My Plugin.

Author: Kenshin

Version: 0.1

Author URI: None

*/

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

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

define('KENSHIN_MP_CSS_URL', KENSHIN_MP_PLUGIN_URL. 'css');

define('KENSHIN_MP_IMG_URL', KENSHIN_MP_PLUGIN_URL. 'images');

define('KENSHIN_MP_INCLUDES_DIR', KENSHIN_MP_PLUGIN_DIR .'/includes');

define('KENSHIN_MP_METABOXES_DIR', KENSHIN_MP_PLUGIN_DIR . '/metaboxes');

define('KENSHIN_MP_POSTS_DIR', KENSHIN_MP_PLUGIN_DIR . '/posts');

if(!is_admin()){

require_once KENSHIN_MP_INCLUDES_DIR. '/frontend.php';

new KenshinFrontend();

}else{

require_once KENSHIN_MP_INCLUDES_DIR. '/backend.php';

new KenshinBackend();

require_once KENSHIN_MP_METABOXES_DIR . '/main.php';

new Kenshin_Myplugin_Metaboxes_Main();

}

require_once KENSHIN_MP_POSTS_DIR . '/product.php';

new Kenshin_Myplugin_Custom_Post_Product();

Các đoạn code bên trong thì có lẽ bạn đã quá quen thuộc rồi nên tôi sẽ không nhắc lại nhé, mà chỉ giải thích những gì thuộc về kiến thức mới thôi.

Lúc này chúng ta sẽ lần lượt thay đổi và bổ sung các giá trị bên trong file product.php để nó phù hợp với tiêu chí mà tôi đang hướng tới.

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

<?php

class Kenshin_Myplugin_Custom_Post_Product

{

public function __construct()

{

add_action('init', array(

$this,

'create'

));

}

public function create()

{

$labels = array(

'name' => __('Books'),

'singular_name' => __('Book'),

'menu_name' => __('KBook'),

'name_admin_bar' => __('KBook'),

'add_new' => __('Add Book'),

'add_new_item' => __('Add New Book'),

'search_items' => __('Search Book'),

'not_found' => __('No products found.'),

'not_found_in_trash' => __('No products found in Trash'),

'view_item' => __('View product'),

'edit_item' => __('Edit product'),

);

$args = array(

'labels' => $labels,

'description' => 'Đây là Custom Post Type KProduct',

'menu_icon' => KENSHIN_MP_IMG_URL . '/icon-setting16x16.png',

'public' => true, // Kích hoạt custom post

'hierarchical' => true,

'show_in_nav_menus' => true, // Hiển thị trong Appearance -> Menus

'show_in_admin_bar' => true, // Hiển thị trên thanh Admin bar màu đen.

'menu_position' => 5, // Thứ tự vị trí hiển thị trong menu

'supports' => array('title' ,'editor','author','thumbnail','excerpt','trackbacks' ,'custom-fields' ,'comments','revisions' ,'page-attributes','post-formats'),

'rewrite' => array('slug'=>'kproduct'),

'_edit_link' => 'post.php?post=%d',

'has_archive' => true, // //Cho phép lưu trữ

'capability_type' => 'post', // Phân quyền

);

register_post_type('kproduct', $args); // Phương thức đăng ký & nạp custom post vào hệ thống.

}

}

Vì nó có quá nhiều tham số ở bên trong nên tôi không thể nào giải thích hết cho bạn được, bạn có thể vào đây để tìm hiểu các tham số đó dùng để làm gì, trong code tôi có chú thích vài tham số rồi đấy.

Kế tiếp chúng ta cũng cần thay đổi code ở file data.php 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

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

<?php

class Kenshin_Myplugin_Metaboxes_Data {

private $_create_id = 'ks-mb-data-';

private $_meta_key = '_ks_mb_data_';

private $_metabox_id = 'ks-mb-data';

public function __construct(){

add_action('add_meta_boxes', array($this, 'create'));

add_action('save_post', array($this, 'save'));

}

public function save($post_id){

// Có giá trị tương đương với $_POST

$postVal = $_POST;

if (!$postVal[$this->_metabox_id . '-nonce']) return $post_id;

if(!wp_verify_nonce($postVal[$this->_metabox_id . '-nonce'],$this->_metabox_id)) return $post_id;

if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id;

if(!current_user_can('edit_post', $post_id)) return $post_id;

$data = array(

'title' => sanitize_text_field($postVal[$this->_create_id . 'title']),

'price' => sanitize_text_field($postVal[$this->_create_id . 'price']),

'author' => sanitize_text_field($postVal[$this->_create_id . 'author']),

'info' => strip_tags($postVal[$this->_create_id . 'info'])

);

foreach ($data as $key => $val){

update_post_meta($post_id, $this->_meta_key . $key ,$val);

}

// Đưa dữ liệu vào table wp_postmeta

/* update_post_meta($post_id, $this->_meta_key . 'title',

sanitize_text_field($postVal[$this->_create_id . 'title']));

update_post_meta($post_id, $this->_meta_key . 'price',

sanitize_text_field($postVal[$this->_create_id . 'price']));

update_post_meta($post_id, $this->_meta_key . 'author',

sanitize_text_field($postVal[$this->_create_id . 'author']));

update_post_meta($post_id, $this->_meta_key . 'info',

strip_tags($postVal[$this->_create_id . 'info'])); */

}

public function create(){

add_action('admin_enqueue_scripts', array($this,'add_css_file'));

add_meta_box($this->_metabox_id, 'Infomation KBook', array($this, 'display'), 'kproduct');

}

public function display($post){

wp_nonce_field($this->_metabox_id, $this->_metabox_id . '-nonce');

echo '<div class="ks-mb-data">';

// Phần tử form Book Title

$inputID = $this->_create_id . 'title';

$inputValue = get_post_meta($post->ID, $this->_meta_key . 'title', true);

$html = '';

$html .= '<label>Title :</label>';

$html .= '<input type="text" name= "'.$inputID.'" id="'.$inputID.'" value = "'.$inputValue.'" size="25" />';

echo $html;

// Phần tử form Book Price

$inputID = $this->_create_id . 'price';

$inputValue = get_post_meta($post->ID, $this->_meta_key . 'price', true);

$html = '';

$html .= '<label>Price :</label>';

$html .= '<input type="text" name = "'.$inputID.'" id = "'.$inputID.'" value = "'.$inputValue.'" size="25" />';

echo $html;

// Phần tử form Book Author

$inputID = $this->_create_id . 'author';

$inputValue = get_post_meta($post->ID, $this->_meta_key . 'author', true);

$html = '';

$html .= '<label>Author :</label>';

$html .= '<input type="text" name = "'.$inputID.'" id = "'.$inputID.'" value = "'.$inputValue.'" size="25" />';

echo $html;

// Phần tử form Book Info

$inputID = $this->_create_id . 'info';

$inputValue = get_post_meta($post->ID, $this->_meta_key . 'info', true);;

$html = '';

$html .= '<label>Infomation :</label>';

$html .= '<textarea name = "'.$inputID.'" id = "'.$inputID.'" rows="6" cols= "50">'.$inputValue.'</textarea>';

echo $html;

echo '</div>';

}

public function add_css_file(){

wp_register_style('ks_mb_data', KENSHIN_MP_CSS_URL . '/mb-data.css', array(),'1.0');

wp_enqueue_style('ks_mb_data');

}

}

Tôi chỉ thay đổi tên hiển thị và phần định dạng kiểu bài viết tôi sửa thành Kproduct cho giống với slug mà tôi đã nạp vào hệ thống. Và đây là kết quả.

Sử dụng WordPress Custom Post Type nâng cao

kproduct-custom-post-type

Khâu chuẩn bị xem như hoàn tất, kế tiếp chúng ta sẽ thử đăng bài mới rồi tiến hành hiển thị dữ liệu đó ra ngoài trang chủ, để thực hiện việc này thì tôi cũng sẽ tiếp tục sử dụng lại Child Themes mà tôi đã sử dụng ở bài trước.

2/ Sử dụng Filter Hook pre_get_posts

Hook này được gọi sau khi đối tượng biến truy vấn được tạo ra, bạn chỉ cần hiểu nôm na là nó giúp bạn lấy ra các kiểu bài viết mà bạn đã tạo mới và nạp vào hệ thống.

Lúc này ở file product.php tôi tạo ra phương thức show_home() và tôi có đoạn code xử lý 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

50

51

52

53

54

55

56

57

58

59

<?php

class Kenshin_Myplugin_Custom_Post_Product

{

public function __construct()

{

add_action('init', array(

$this,

'create'

));

add_filter('pre_get_posts', array($this, 'show_home'));

}

public function show_home($query){

if (is_home() && $query->is_main_query()){

$query->set('post_type',array('post','kproduct'));

}

return $query;

}

public function create()

{

$labels = array(

'name' => __('Books'),

'singular_name' => __('Book'),

'menu_name' => __('KBook'),

'name_admin_bar' => __('KBook'),

'add_new' => __('Add Book'),

'add_new_item' => __('Add New Book'),

'search_items' => __('Search Book'),

'not_found' => __('No products found.'),

'not_found_in_trash' => __('No products found in Trash'),

'view_item' => __('View product'),

'edit_item' => __('Edit product'),

);

$args = array(

'labels' => $labels,

'description' => 'Đây là Custom Post Type KProduct',

'menu_icon' => KENSHIN_MP_IMG_URL . '/icon-setting16x16.png',

'public' => true, // Kích hoạt custom post

'hierarchical' => true,

'show_in_nav_menus' => true, // Hiển thị trong Appearance -> Menus

'show_in_admin_bar' => true, // Hiển thị trên thanh Admin bar màu đen.

'menu_position' => 5, // Thứ tự vị trí hiển thị trong menu

'supports' => array('title' ,'editor','author','thumbnail','excerpt','trackbacks' ,'custom-fields' ,'comments','revisions' ,'page-attributes','post-formats'),

'rewrite' => array('slug'=>'kproduct'),

'_edit_link' => 'post.php?post=%d',

'has_archive' => true, // //Cho phép lưu trữ

'capability_type' => 'post', // Phân quyền

);

register_post_type('kproduct', $args); // Phương thức đăng ký & nạp custom post vào hệ thống.

}

}

Đoạn code trên sẽ thực hiện việc kiểm tra điều kiện hiển thị các bài viết là chỉ cho phép các bài viết với kiểu Custom Post có slug là kproduct chỉ hiển thị duy nhất ở ngoài trang chủ.

Quay lại trang chủ và bấm F5 thì bạn sẽ thấy bài viết bạn vừa tạo được hiển thị ngoài trang chủ như hình.

Sử dụng WordPress Custom Post Type nâng cao

home-custom-post-type

Và khi tôi click vào để xem chi tiết bài thì kết quả sẽ là.

Sử dụng WordPress Custom Post Type nâng cao

metaboxes-custom-post

3/ Lời kết

Tôi vừa hướng dẫn bạn Sử dụng WordPress Custom Post Type nâng cao, qua đó bạn có thể kết hợp nhiều thứ với nhau để tạo ra một kiểu bài viết riêng biệt theo đúng ý đồ của bạn. Và cũng xin nói luôn đây là bài viết cuối cùng trong Series Hướng dẫn lập trình WordPress 4.x , nhưng bạn yên tâm vì sắp tới tôi sẽ thu xếp và viết thêm hàng loạt bài viết nâng cao, và cũng sẽ suy xét xem có nên ra Series Hướng dẫn lập trình Themes WordPress hay không, chào thân ái và quyết thắng.

Series Navigation<< Hiển thị WordPress Meta boxes ngoài trang chủ

Nguồn: laptrinhweb.org

Last updated