UPDATE #1 - June 4th, 2007
- added handy functions for easier view management
- added improvements suggested by novaphoenix (thanks!)
UPDATE #2 - July 19th, 2007
- added TRUE as third parameter to $this->view->part() method to tell the library to render the partial immediately. This resolves a possible namespace conflict that Al James pointed out in this post. The conflict only arises if you want to use the same partial view more than once on a given page.
UPDATE #3 - July 28th, 2007 (revised) - full details here
- added support for sending no-cache headers to browser, upon request of Code Arachn!d
- added support for parsed templates, upon request from Athfar
- added support for a config/View.php file for storing configuration values
- added phpDoc-style comments
I’ve always found the default nature of view and view data handling in CI to be awkward at best. Therefore, a few months ago, I solved that problem for myself by creating a “View” library that is automatically loaded.
Let’s look at some examples of how we can address the awkwardness.
The requirement to pass a data array into $this->load->view().
Normally, we do this:
1. create a $data array, quite often with a different line of code for each item in the array.
2. pass it into the view
$data['name'] = 'Easter Bunny';
$data['treat'] = 'chocolate';
$this->load->view('template', $data);
By using a View library, this can be written as:
$this->view->set('name', 'Easter Bunny');
$this->view->set('treat', 'chocolate');
$this->view->load('template');
Same amount of code, but much easier to read, and much more flexible, as you’ll begin to see.
How do we assign data to the view when in the constructor?
Because the View library would already be loaded, it would be available in constructors, which is always an awkward problem for some projects.
$this->view->set('variable', 'value');
One line of code per variable. No need to mess around with controller-wide variables, globals, or other fancy gimmicks.
What about those annoying partials (views within views)?
I handle partials by having a variable in my main view that the partial’s html gets assigned to. I know not everyone will do it this way, but let’s continue so you can see how a View library might make this easy for you.
Say you have 3 view files (a main template, and two sub-views that get included into it):
/views/main_template.php
/views/left_column.php
/views/right_column.php
The main template has a placeholder variable for each partial, such as $left_column and $right_column. Now, we just need to assign the partials and display the view:
$this->view->part('left_column', 'left_column.php'); // (file extensions added for clarity)
$this->view->part('right_column', 'right_column.php');
...
$this->view->load('main_template');
No need for a view to include a subview directly. You can do that in one line of code, as shown. Upon rendering the main template, the subviews are rendered and the resulting code is assigned to respective view variables which are automatically passed to the main view.
What about libraries and models?
When data from a library needs to be passed to the view, we find ourselves passing it back to the controller function and then assigning it as shown above. Well, why not just assign it directly to the view inside our library or model?
In a library or model:
$obj =& get_instance();
$obj->view->set('variable', 'value');
You want to be careful not to break the MVC rules of conduct, so the choice to do this will depend on the role of library or model function called. You always have the option to pass data back to the controller and assign to the view from there.
$this->view->set('variable', $this->some_library->get_some_value());
I’ll post a working library here and may add something to the Wiki. Feel free to chime in with questions and comments.
