25. Hướng dẫn xây dựng WordPress Widget Support

Đáng lẽ hôm nay tôi sẽ chia sẽ với bạn một phần khá là quan trọng trong WordPress đó là Custom Post, nhưng vì thời gian cận lễ nên tôi chưa có chuẩn bị xong dàn bài nên tạm thời sẽ Hướng dẫn xây dựng WordPress Widget Support. Nói support cho nó sang chảnh vậy thôi chứ thành phần tạo nên Widget cũng đơn giản lắm, nhưng trong bài tôi sẽ chia sẽ với bạn một số kỹ thuật quản lý Widget khá hay.

1/ Cấu trúc plugin kenshin support

Vẫn như thường lệ tôi sẽ tạo mới một plugin để tương tác cho nó tiện hơn.

Cấu trúc plugin

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

Đây là toàn bộ cấu trúc plugin của tôi.

cau-truc-plugin-support

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

<?php

/**

* @package Kenshin Support

* @version 0.1

*/

/*

Plugin Name: Widget Support Demo

Plugin URI: http://laptrinhweb.org

Description: Đây là một plugin dùng để xây dựng Widget Support.

Author: Kenshin

Version: 0.1

Author URI: None

*/

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

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

define('KENSHIN_SP_INCLUDES_DIR', KENSHIN_SP_PLUGIN_DIR .'/includes');

define('KENSHIN_SP_CSS_URL', KENSHIN_SP_PLUGIN_URL . 'css');

define('KENSHIN_SP_DIR', KENSHIN_SP_PLUGIN_DIR . '/widgets');

define('KENSHIN_SP_HTML_DIR', KENSHIN_SP_DIR . '/html');

if(!is_admin()){

require_once KENSHIN_SP_INCLUDES_DIR. '/frontend.php';

new KenshinFrontend();

}else{

require_once KENSHIN_SP_INCLUDES_DIR. '/backend.php';

new KenshinBackend();

}

require_once KENSHIN_SP_DIR. '/main.php';

new Kenshin_Widget_Support_Main();

Nhìn vào cấu hình các hằng số thì tôi chắc rắng bạn đã quá quen thuộc với nó rồi nên tôi sẽ không giải thích lại, ở đây tôi sẽ dùng file main.php nằm trong folder widgets để quản lý Widget sau này của tôi. Bạn có thể xem lại bài Tạo mới WordPress Widget đơn giản, thì sẽ thấy ngay bất cập ở chỗ nếu plugin của bạn có nhiều Widget chả lẽ bạn cứ xử lý thủ công theo kiểu này sao.

1

2

3

4

5

add_action('widgets_init', 'ks_widget_register_simple');

function ks_widget_register_simple(){

register_widget('Kenshin_Widget_Simple');

}

Giả sử plugin của bạn có 10 Widget thì bạn sẽ xử lý như thế nào? cứ viết tứng phương thức rồi add vào Hook Action hả, hoặc đơn giản hơn là tạo một array để chứa toàn bộ tên của các phương thức rồi dùng vòng lặp foreach để xử lý, nhưng cách này cũng chưa thật sự tối ưu cho lắm. Trong quá trình tôi nghiên cứu thì tôi nảy sinh ra được một kỹ thuật khá hay, nó sẽ giúp cho bạn bật tắt Widget một cách đơn giản nhất.

2/ Cấu trúc file main.php trong Widget Support

Bên trong file này cũng không có xử lý gì nhiều cả, có lẽ bạn sẽ há hốc miệng khi tôi show đoạn code 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

<?php

class Kenshin_Widget_Support_Main{

private $_widget_options = array();

public function __construct(){

// True = load widget

// false = Khong load widget

$this->_widget_options = array(

'support' => true,

);

foreach ($this->_widget_options as $key => $val){

if ($val == true){

add_action('widgets_init', array($this, $key));

}

}

}

public function support(){

require_once KENSHIN_SP_DIR . '/support.php';

register_widget('Kenshin_Widget_Support');

}

}

Đầu tiên tôi sẽ khởi tạo một biến toàn cục $_widget_options , sau đó ngay tại vị trí hàm khởi tạo construct tôi gọi tới biến toàn cục bằng cú pháp $this->_widget_options và nó là một mảng dùng để chứa tên phương thức của các Widget, và nó có hai giá trị true & false.

Tức là khi bạn set Widget có giá trị bằng true có nghĩa là bạn đang bật nó lên và cho phép nó hoạt động, Khi nó có giá trị bằng false thì nó sẽ bị tắt đi và không hiển thị trong vùng admin cũng như ngoài trang chủ. Với kỹ thuật này thì bạn plugin của bạn có bao nhiêu Widget cũng quản lý dễ dàng.

Sau đó tôi dùng vòng lặp foreach và kiểm ra nếu Widget có giá trị bằng true thì mới cho phép nạp Widget vào hệ thống để tương tác với website, phần xử lý vòng lặp thì tôi sẽ không giải thích vì nó thuộc kiến thức căn bản.

Phương thức support() chính là nơi tôi gọi tới file support.php (File xử lý Widget Support), và đăng ký nó vào hệ thống, và tên phương thức sẽ được đưa vào phần mảng ở hàm khởi tạo trong file main.php.

Kế tiếp tôi sẽ bắt tay xây dựng phần hiển thị Widget Support trong vùng admin và đưa các dữ liệu từ form vào database và cuối cùng sẽ hiển thị phần dữ liệu đó ngoài phần themes.

3/ Cấu trúc file support.php trong Widget Support

Đầu tiên sẽ là phần khai báo tên Widget, classname và mô tả của nó 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

<?php

class Kenshin_Widget_Support extends WP_Widget {

public function __construct() {

$id_base = 'kenshin-widget-support';

$name = 'Kenshin Support';

$widget_options = array(

'classname' => 'kenshin-wg-css-support',

'description' => 'Widget Support Online'

);

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 ) {

}

}

Phần khai báo này thuộc kiến thức cũ nên nếu bạn có quên thì mời xem lại bài mà tôi đã dẫn link ở phía trên. Kế tiếp tôi sẽ khai báo 4 textbox cho phần form.

Các textbox lần lượt sẽ là title, name, phone, yahoo, title là tên hiển thị ngoài trang chủ của Widget, name là họ tên người support (hỗ trợ), phone với yahoo khỏi nói hen.

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

<?php

class Kenshin_Widget_Support extends WP_Widget {

public function __construct() {

$id_base = 'kenshin-widget-support';

$name = 'Kenshin Support';

$widget_options = array(

'classname' => 'kenshin-wg-css-support',

'description' => 'Widget Support Online'

);

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 ) {

// 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 họ tên (name)

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

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

$inputValue = $instance['name'];

echo '<p>';

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

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

echo '</p>';

// Phần từ Form phone (điện thoại)

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

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

$inputValue = $instance['phone'];

echo '<p>';

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

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

echo '</p>';

// Phần từ Form yahoo

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

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

$inputValue = $instance['yahoo'];

echo '<p>';

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

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

echo '</p>';

}

}

Sau khi khai báo xong phần form thì tôi vào vùng admin tìm đến khu vực quản lý Widget theo chỉ mục Appearance->Widgets, và nhân đây cũng nói luôn là tôi sẽ tiếp tục dùng themes Twenty Ten và sẽ kéo nó vào vùng Sidebar thứ nhất trong themes là Primary Widget Area, với cấu trúc của themes này thì phần Widget Support sẽ hiển thị ở bên tay phải mản ảnh nhỏ của bạn.

widget-support-form

Phần xử lý tạo ra các ô texbox trong phương thức form() xem như hoàn tất, tiếp theo sẽ nhập liệu và sử dụng phương thức update() đưa dữ liệu từ form vào database. Cái này thì quá đơn giản luôn nha và cũng đã thực hành rồi nên tôi sẽ lướt nhanh và không nhắc lạ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

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

<?php

class Kenshin_Widget_Support extends WP_Widget {

public function __construct() {

$id_base = 'kenshin-widget-support';

$name = 'Kenshin Support';

$widget_options = array(

'classname' => 'kenshin-wg-css-support',

'description' => 'Widget Support Online'

);

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

}

public function widget( $args, $instance ) {

}

public function update( $new_instance, $old_instance ) {

// Gán biến instance bằng với giá trị cũ

$instance = $old_instance;

// Đưa dữ liệu vào hàm strip_tags loại bỏ các ký tự html

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

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

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

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

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 họ tên (name)

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

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

$inputValue = $instance['name'];

echo '<p>';

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

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

echo '</p>';

// Phần từ Form phone (điện thoại)

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

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

$inputValue = $instance['phone'];

echo '<p>';

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

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

echo '</p>';

// Phần từ Form yahoo

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

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

$inputValue = $instance['yahoo'];

echo '<p>';

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

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

echo '</p>';

}

}

Ok, bây giờ nhập đại giá trị vào các textbox rồi nhấn save xem nó có lưu giữ lại các giá trị vừa mới nhập ở textbox hay không.

record-form-widget-support

Ok con gà cồ rồi nha, giờ tới công đoạn hiển thị dữ liệu của Widget Support ra ngoài trang chủ. Tôi sẽ thay đổi cách hiển thị dữ liệu từ Widget một tí, tức là tôi sẽ không gọi dữ liệu ngay tại phương thức widget(), mà tôi sẽ gọi nó ở một file khác và sẽ dùng phương thức require() kéo nó vào.

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

<?php

class Kenshin_Widget_Support extends WP_Widget {

public function __construct() {

$id_base = 'kenshin-widget-support';

$name = 'Kenshin Support';

$widget_options = array(

'classname' => 'kenshin-wg-css-support',

'description' => 'Widget Support Online'

);

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

}

public function widget( $args, $instance ) {

extract($args);

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

echo $before_widget;

if (!empty($title)){

echo $before_title. $title . $after_title;

}

require KENSHIN_SP_HTML_DIR .'/support.php';

echo $after_widget;

}

public function update( $new_instance, $old_instance ) {

// Gán biến instance bằng với giá trị cũ

$instance = $old_instance;

// Đưa dữ liệu vào hàm strip_tags loại bỏ các ký tự html

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

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

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

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

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 họ tên (name)

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

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

$inputValue = $instance['name'];

echo '<p>';

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

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

echo '</p>';

// Phần từ Form phone (điện thoại)

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

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

$inputValue = $instance['phone'];

echo '<p>';

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

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

echo '</p>';

// Phần từ Form yahoo

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

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

$inputValue = $instance['yahoo'];

echo '<p>';

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

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

echo '</p>';

}

}

Tôi dùng action apply_filters() để lọc bỏ đi các ký tự không cần thiết trước khi nạp tên Widget vào hệ thống và cho phép nó hiển thị ngoài trang chủ.

Quan sát trong code bạn sẽ thấy tôi goj tới file support.php nằm trong chỉ mục widgets/html/support.php, tức là phần xử lý đổ dữ liệu ra ngoài trang chủ.

Nội dung file widget/html/support.php:

1

2

3

4

5

<ul class="kenshin-wg-css-support">

<li>Họ tên: <?php if (!empty($instance['name'])) echo $instance['name']; ?></li>

<li>Điện thoại: <?php if (!empty($instance['phone'])) echo $instance['phone']; ?></li>

<li>Yahoo: <?php if (!empty($instance['yahoo'])) echo $instance['yahoo']; ?></li>

</ul>

Ra ngoài trang chủ F5 lại trình duyệt và tôi có kết quả như hình.

show-widget-support-in-homepage

Lúc này bạn chú ý tôi có gán phần classname là kenshin-wg-support-css vào thẻ <ul và giờ tôi sẽ định dạng một tí css để phần hiển thị Widget được bắt mắt hơn.

Để xử lý định dạng css thì tôi sẽ tạo thêm phương thức add_css() và đoạn code xử lý như sau.

1

2

3

4

5

6

public function add_css(){

$cssUrl = KENSHIN_SP_CSS_URL;

wp_register_style('ks_wg_support', $cssUrl . '/style.css', array(), '1.0');

wp_enqueue_style('ks_wg_support');

}

Phương thức wp_register_style() có tất cả là 4 tham số, đầu tiên là id (Điền gì cũng được) tiếp đó là phần đường dẫn gọi tời file css và một array rỗng và version cho file css này là bao nhiêu.

Phương thức wp_enqueue_style() có duy nhất 1 tham số chính là ID vì nó xác định ID đề xử lý gọi đúng file css đã được chỉ định mà bạn đã gán ở phần tham số đầu tiên của phương thức wp_register_style().

http://localhost/wordpress/wp-content/plugins/kenshin-support/css/style.css?ver=1.0′, đây là phần đướng dẫn gọi tới file css theo đúng chuẩn mà WordPress đề ra nếu bạn sử dụng hai phương thức trên.

Và đây là phần code của file style.css.

1

2

3

4

5

6

7

8

9

10

11

12

13

.kenshin-wg-css-support{

margin-top:10px;

}

.kenshin-wg-css-support ul{

background-color: #ccc;

}

.kenshin-wg-css-support li{

padding: 5px;

font-size: 14px;

border-bottom: 1px solid #FFF;

}

Save mọi thứ lại và F5 lại trang chủ và tôi có được kết quả như mong muốn.

style-widget-support-homepage

3/ Lời kết

Kết thúc bài Hướng dẫn xây dựng WordPress Widget Support thì bạn đã bổ sung thêm cho mình một kỹ thuật quản lý Widget khá bổ ích, tuy nhiên dưới góc độ của một số coder chuyên nghiệp thì họ sẽ không hài lòng với cách này, vì nó vẫn còn gọi là xử lý thủ công, tôi có một Idea như là bạn tạo một page setting và có các nút checkbox với từng Widget, nếu bạn check vào thì xem như active Widget và ngược lại, lúc ấy bạn sẽ không cần phải can thiệp vào code để bật tát Widget nửa. Ở bài kế tiếp tôi sẽ sử dụng lại cấu trúc plugin này và sẽ tạo thêm một Widget nửa để minh họa cho bạn xem khi plugin tôi có tới 2 Widget thì tôi sẽ xử lý nó ra sao.

Series Navigation<< Sử dụng WordPress Template Tags toàn tậpHướng dẫn xây dựng WordPress Widget Video >>

Nguồn: laptrinhweb.org

Last updated