Tự tạo thư viện load widget trong codeigniter

Như các bạn biết mặc định hệ thống của Codeigniter hoạt động theo mô hình MVC, như vậy ở một controller bắt buộc phải load tất cả các phần header, footer, slidebar, ... điều này đôi khi làm làm phiền toái cho coder vì khó quản lý nó. Vậy hôm nay mình sẽ hướng dẫn các bạn tự viết một thư viện load widget.

Widget có thể coi là một block, một thành phần của website, hiện tại trên mạng có rất nhiều thư viện load widget và các bạn có thể download về và sử dụng nhưng tôi nghĩ các bạn cũng nên đọc qua bài này  vì trong bài sẽ giải thích cách bạn viết một thư viện ngoài.

Trước khi vào viết tôi giới thiệu cấu trúc folder widget như sau:

Các bạn thấy tôi đã tạo một folder widgets trong folder application. và mỗi widget sẽ có 2 file chính là controller và view, trong đó file controller dùng để xử lý và gọi đến file view để hiển thị.

Viết thư viện cho controller widget

Để hiểu được phần này bạn phải đọc qua bài overwrite bộ core trong codeigniter nhé

Trước tiên các bạn vào thư mục application/core tạo một file MY_Widget.php và MY_Loader.php có nội dung như sau:

File MY_Widget.php

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class MY_Widget
{
        function __get($key)
    {
        $CI =& get_instance();
        return $CI->$key;
    }
        
        function __set($key, $val)
        {
                $CI =& get_instance();
                if (isset($CI->$key))
                    $CI->$key = $val;
                else
                    $this->$key = $val;
        }
}
?>

Hàm này dành cho các controller trong widget extends tới nó. Mặc định tất cả các lớp  controller trong widget đều tuân theo quy tắc đặt tên chữ hoa đầu tiên và tên lớp bắt đầu bằng tên folder sau đó kèm với chữ _widget.

 

File widgets/header/controller.php có nội dung như sau:

 

1
2
3
4
5
6
7
8
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class Header_widget extends MY_Widget
{
    function index(){
        $this->load->view('view');
    }
}

Nội dung của file này là tạo một controller với tên Header_widget kế thừa lớp MY_Widget và cuối cùng là load file view.php tương ứng bên dưới nó.

 

File widgets/header/views.php có nội dung như sau:

 

1
<h1>Đây là header</h1>

Vậy là bạn đã tạo được một widget thành công rồi, bước tiếp theo là ta sẽ tạo một hàm load widget dành cho controller chính.

 

Viết hàm load widget

Hàm này tôi sẽ viết nó trong file MY_Loader với nội dung 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
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
require 'MY_Widget.php';
class MY_Loader extends CI_Loader
{
    public function widget($widget_directory, $agrs = array())
    {
        // Đường dẫn đến file controller widget
        $path = APPPATH . 'widgets/' . $widget_directory . '/controller.php';
        
        // Tên controller widget
        $class_name = ucfirst(str_replace('/', '_', $widget_directory)) . '_widget';
 
        // Kiểm tra widget tồn tại ko
        if (!file_exists($path)) {
            show_error('The Widget ' . $path . ' Not Found');
        }
 
        //--------------------------------
        // Tạo đường dẫn để load file view trong widget
        $this->_ci_view_paths = array(APPPATH . 'widgets/' . $widget_directory . '/' => TRUE);
 
        //--------------------------------
        // Load Widget
        require_once($path);
 
        if (!class_exists($class_name)) {
            show_error("Class Name Widget $class_name Not Found, URL Is $path");
        }
 
        $MD = new $class_name;
 
        if (!method_exists($MD, 'index')) {
            show_error("Method Index Of Widget $class_name Not Found, URL Is $path");
        }
 
        ob_start();
        call_user_func_array(array($MD, 'index'), $agrs);
        $content = ob_get_contents();
        ob_end_clean();
 
        // Trả lại phương thức load views cho hệ thống CI
        $this->_ci_view_paths = array(APPPATH . 'views/' => TRUE);
 
        return $content;
    }
 
}
 
?>

Trong đó đoạn code require 'MY_Widget.php'; sẽ load file MY_Widget vào hệ thống, nếu như không có dòng này thì trong các controller widget không thể extends lớp này được vì nó không tồn tại.

 

Hàm widget có 2 tham số truyền vào, $widget_directory là đường dẫn đến widget cần load,$agrs là mảng các biến muốn truyền vào widget

Đoạn code dưới đây dùng để thiết lập vị trí view cho widget

 

1
2
3
//--------------------------------
        // Tạo đường dẫn để load file view trong widget
        $this->_ci_view_paths = array(APPPATH . 'widgets/' . $widget_directory . '/' => TRUE);

Và sau khi load widget thì trả lại vị trí view cho folder view chính của hệ thống

 

 

1
2
// Trả lại phương thức load views cho hệ thống CI
        $this->_ci_view_paths = array(APPPATH . 'views/' => TRUE);

 

Gọi Widget Từ Controller Chính

Bạn tạo một controller welcome.php với nội dung như sau:1

 

1
2
3
4
5
6
7
8
9
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class Welcome extends CI_Controller {
    public function index()
    {
        echo $this->load->widget('header');
    }
}
?>

Nhìn vào code đơn giản đúng không nào, để load widget thì chỉ cần gọi $this->load->widget('widget_name', array('cac_bien_truyen_vao'))

 

Bạn chạy controller này lên màn hình sẽ xuất hiện dòng chữ Đây là header, và đây cũng chính là nội dung trong file view của widget header.

Truyền biến vào widget

Đôi lúc ta cũng cần truyền biến vào widget để xử lý, ta làm như sau:

Controller welcome.php

 

1
2
3
4
5
6
7
8
9
10
11
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class Welcome extends CI_Controller {
    public function index()
    {
                $title = 'Hướng dẫn tạo widget';
                $content = 'Tự tạo widget cho riêng mình';
        echo $this->load->widget('header', array($title, $content));
    }
}
?>

File widgets/header/controller.php

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class Header_widget extends MY_Widget
{
    // Nhận 2 biến truyền vào
    function index($title, $content){
        
        // truyền qua view
        $this->load->view('view', array(
            'title' => $title,
            'content' => $content
        ));
    }
}

File widgets/header/view.php

 

 

1
2
3
<h1><?php echo $title ?></h1>
 
<h3><?php echo $content; ?></h3>

Thật đơn giản đúng không nào, muốn truyền biến qua widget thì khai báo hàm load widget và bên controller widget sẽ nhận với các biến tương ứng.

 

Load Model, Library, Helper trong widget

Ở mỗi widget ta load model, helper, library, language một cách bình thường nhé, vì bản chất nó cũng là instance của codeigniter.

Ví dụ:

$this->load->view()

$this->load->model()

$this->load->library()

$this->load->helper()

Lời kết

Qua bài này các bạn có thể tự tạo cho mình một thư xử lý widget rồi đúng không nào, đoạn code mình viết có thể chưa tối ưu nên nếu các bạn có ý kiến khác thì hãy bổ sung góp ý giúp mình với nhé, và mình có gửi file Download đính kèm. Cuối cùng cám ơn các bạn đã đọc bài này và chúc các bạn vui vẻ khi tham gia freetuts.net.

t

Thiên Tác Giả

Mình Tên là Thiên, hơi điên một chút. Chuyên viết về kinh doanh

Bình luận


Vui lòng đăng nhập để bình luận bài viết. Đăng nhập tại đây

2017 Team .net