Codeigniter – better way to load views

Codeigniter is great framework, but sometimes it feels like you have to do more work than it would be necessary. For example, loading views at first seems easy and straight forward.

1
$this->load->view('view_file', $data);

However, in a real world project you would rarely use only one view file, each controller would probably have to load views in multiple functions and there would be several controllers. It’s obvious we need something better.

The solution is easy, we need to define a method for loading views and put it in a base class that our controllers would extend. In Codeigniter this is done by creating My_Controller.php file and placing it in application/core/ directory. Our controllers can now extend MY_Controller instead of CI_Controller. All of these names are case sensitive. So, this is how this method looks like:

1
2
3
4
5
6
7
8
9
10
11
12
protected function loadViews($template, $data = null){
        if(!isset($data)){
            $data = $this->_viewData;
        }
        if(!isset($data['urls'])){
            $data = array_merge($this->_viewData, $data);
        }
        $this->load->view('common/header',$data);
        $this->load->view('common/navbar',$data);
        $this->load->view($template, $data);
        $this->load->view('common/footer', $data);
    }

loadViews() method doesn’t need to be public, so making it protected is the best choice. Note that I wasn’t following the Codeigniter naming convention here. All method names are written with underscores, I chose camel case deliberately to make my code distinct, you can make your own choices here.

Whenever we need to load views in our controllers we would simply type:

1
$this->loadViews('view_file', $data);

Now you might be wondering about $_viewData property. Here’s the whole MY_Controller file that I use in my projects:

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
class MY_Controller extends CI_Controller {

    protected $_viewData = array();    //holds data that is being passed to view files, read from config file

    public function __construct(){
        parent::__construct();
        $this->config->load('my_config', TRUE);    //my_config is my custom configuration file
        $this->setViewData();
    }

    private function setViewData(){
        $this->_viewData = $this->config->item('my_config');
    }  

        /**
        *    Loads views
        *
        *    @param string $template Name of the template file
        *    @param array $data Data array that is being passed to the views
        */

    protected function loadViews($template, $data = null){
        if(!isset($data)){
                        //if no data is passed, use only $_viewData
            $data = $this->_viewData;
        }
        if(!isset($data['urls'])){
                        //some data is passed, but this is not whole $_viewData array from the config file
                        //$data['urls'] is something I always have in my configuration files
            $data = array_merge($this->_viewData, $data);
        }
        $this->load->view('common/header',$data);
        $this->load->view('common/navbar',$data);
        $this->load->view($template, $data);
        $this->load->view('common/footer', $data);
    }

I use a configuration file to hold basic data such as navigation links, links to files, etc. I load this into MY_Controller and pass that array to views, so whenever I load views I have the same basic set of data, plus the data necessary for the current view. I also have a choice of calling loadViews() in my controllers without passing any data, passing only the data I need for the one specific view, or passing all of the (view) data. Controllers can, of course, override loadViews() method if that is necessary.

Codeigniter is very flexible and people are using it in many different ways. I’d just like to know how many other developers have come up with the same approach as I did.

Read More