CodeIgniter Forums
In the interests of DRY - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forum-23.html)
+--- Thread: In the interests of DRY (/thread-14712.html)



In the interests of DRY - El Forum - 01-12-2009

[eluser]underskor[/eluser]
At the end of each of my controllers functions I am setting the same dynamic(ish) footer variables that are passed to the master view. I think _output is what I need to look into, but I can't find a great deal of documentation on it's use other than the user guide.

Is this how it works?
Code:
function one() {
//[..]
$master_view['main_content'] = 'content1';
}

function two() {
//[..]
$master_view['main_content'] = 'content2';
}

function three() {
//[..]
$master_view['main_content'] = 'content3';
}

function _output($master_view) {
    $master_view['footer'] = 'footer';
    $this->load->view('master_view', $master_view);
}

Could someone please share some examples of _output usage, or explain their method of coding to the DRY concept?


In the interests of DRY - El Forum - 01-13-2009

[eluser]AndrewMalachel[/eluser]
I think, you should add at the end of every function (in this case function one to function three):

$this->_output($master_view['main_content']);

so at the end of each function, will call the _output function..

for ex.:
Code:
function one() {
//[..]
$master_view['main_content'] = 'content1';
$this->_output($master_view['main_content']);
}



In the interests of DRY - El Forum - 01-13-2009

[eluser]AndrewMalachel[/eluser]
Mmm... I think you could solved it a little easier if you just write these..
Code:
function [your_class_controller_name]() {
    parent::Controller();
    $this->master_view['footer'] = 'footer';
    $this->master_view['main_content'] = 'default'; // your default main_content
}

function one() {
    //[..]
    $this->master_view['main_content'] = 'content1';
    $this->_output();
}

// ... also the same to function 2 and 3

function _output() {
    $this->load->view('master_view', $this->master_view);
}
Anyway, you either can use any that you think suite you...
Also you can define the master_view variable in your class as an array:
Code:
Class [your_class_controller_name] extends Controller {
    var $master_view = array();

    function .... // and the rest just like above...
}
and use the master_view variable as above.. (with the '$this->...')

well, hope it works... Smile
(and I hope I don't confuse you even more!)


In the interests of DRY - El Forum - 01-13-2009

[eluser]underskor[/eluser]
Thanks for your reply, Andrew. Your second example looks like the way to go. I will test it out and report back.


In the interests of DRY - El Forum - 01-13-2009

[eluser]AndrewMalachel[/eluser]
U're welcome...
I'm glad if it could help you, since I have search any reference to it and it took me days to solve them...
I hate to see others digging up like me...

just let me know when everything works well... also if it doesn't... (well, i hope it does... Smile )


In the interests of DRY - El Forum - 01-13-2009

[eluser]xwero[/eluser]
You can use a layout library for this sort of thing or you can use a hooks


In the interests of DRY - El Forum - 01-13-2009

[eluser]underskor[/eluser]
Had a few troubles with there being 0 output, then there being 2x the output, but got there in the end. For anyone who may be interested, here is the idea behind it. Hope it saves someone some time. Big thanks to Andrew for his help.
Code:
class Test extends Controller {
    var $master_view_data = array();

    function Test()    {
        parent::Controller();
        $this->master_view_data['header'] = 'HEADER';
        $this->master_view_data['footer'] = 'FOOTER';
    }

    function index() {
        $this->master_view_data['body'] = 'BODY';
    }

    function view_spoons() {
        //Get spoons
        [..]

        $this->master_view_data['body'] = $spoons;
    }
    
    function _output() {
        echo $this->load->view('master_view', $this->master_view_data, TRUE);
    }
}

A few points I had trouble with:
* _output() is called automatically, so $this->_output() at the end of your function = output x 2
* _output() does not echo your data automatically

Also, is it just me or is _output() bit counter-intuitive in regards to arguments? To pass an argument to _output(), you must call it right? (bring on the 2x output) Unless you do something like the following:
Code:
var $output;

function index() {
    $this->output = 'page';
}

function _output($this->output) {
    echo $this->output;
}

..in which case, you may aswell leave the _output() argument out? Maybe I've missed something. Anyone got any ideas?


In the interests of DRY - El Forum - 01-13-2009

[eluser]AndrewMalachel[/eluser]
Ahhh... yes.. it's my mistakes...

I just read the user_guide manual again, and I believe I'd skipped the
"function _output" parts...

This function doesn't need to be called since if you put it in your controller,
CI will automatically call it at the and of it process, as a post-process,
before the data are sent to the browser...

and the first parameter of the function holds the output 'raw' material..
from what I'd read, (I think) you can get the raw by using the third
parameter of the load-view function...
i.e:
Code:
$this->output = $this->load->view('my_view', $my_data, TRUE);
and the output:
Code:
function _output(){
echo $this->output;
or maybe..
Code:
function _output($data = $this->output){
echo $data;
The above code has never been tested before by me..
hope I get it right...

Since I'd never use the _output function, I totally forgot about it..
Let me dig up and try something with the _output function...
hope I can paid up my mistakes above...
just wait...

Ugh.. shame on me...


In the interests of DRY - El Forum - 01-14-2009

[eluser]underskor[/eluser]
No biggie mate. Smile It's all working great now. Thanks again!


In the interests of DRY - El Forum - 01-14-2009

[eluser]JoostV[/eluser]
You can also just use nested views. That way, you don't need to repeatedly load view from every controller.

1. Just call the main view from your controller:
Code:
// Define a custom subview for this page
$master_view['sub_view'] = 'my_subview';
$this->load->view('master_view', $master_view);

2. In your master view file you can load all subviews that you need:
Code:
$this->load->view('header');
$this->load->view('navbar');

// This is where we will load our custom subview
$this->load->view($my_subview);

$this->load->view('footer');

Make sure to pass all data that your subviews will need in variable $master_view. E.g., if you need to set up a navbar you can do that in the __construct of a special navbar model and store it in $master_view['navbar']. Autolad the model and $master_view['navbar'] will be created automatically for every page.