CodeIgniter Forums

Full Version: Automatic Layout Inclusion
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3

El Forum

[eluser]Drarok[/eluser]
Good morning!
I'm brand new to CI, but not to PHP. I'm trying out various frameworks, trying to find a quick way to bash out some sites.

I've had a look around these here forums, found that someone has created a 'View' library that sort of addresses my issue, but not in the way I'd like.

What I want to do is to write a single outline document (or maybe a header and a footer) that is/are automatically included for every view, so that my view files can just contain the content they will output, with no need to write:
$this->load->view('header');
$this->load->view('section/theview');
$this->load->view('footer');
etc.

I just want to have this in my controller:
$this->load->view('section/index');
and no include() calls or the like in the view at all.

Is this currently possible, or should I start writing my own implementation? I think it would be much tidier this way. It's the way I'm used to working with my own 'frameworks' that I normally use, and also another PHP framework I tried implements templates this way.

Thanks in advance, and apologies if this is glaringly obvious.

El Forum

[eluser]Michael Wales[/eluser]
FAQ

El Forum

[eluser]coolfactor[/eluser]
Put the common stuff into your constructor, or another function that you call.

This is where the View library you spoke of comes in handy. Let's look at an example. Say you've written a page "Layout" library that encapsulates all the repetitive stuff:

Code:
class Layout {
    var $CI;

    function Layout() {
        $this->CI =& get_instance();    // just do once
    }

    // standard template, header, footer
    function prepare_template() {
        $this->CI->view->part('header', 'path/to/header/file');
        $this->CI->view->part('footer',  'path/to/footer/file');
    }

    // a different template, header, footer
    function prepare_other_template() {
        $this->CI->view->part('header', 'other_header_file.php');
        $this->CI->view->part('footer',  'other_footer_file.php');
    }

}

Compare that to trying to do that the "CI way", which involves longer, hard-to-read lines of code:
Code:
class Layout {
    var $CI;

    function Layout() {
        $this->CI =& get_instance();    // just do once
    }

    // standard template, header, footer
    function prepare_template() {
        $data['header'] = $this->CI->load->view('path/to/header/file', '', TRUE);
        $data['footer'] = $this->CI->load->view('path/to/footer/file', '', TRUE);
        $this->CI->load->vars($data);
    }

    // a different template, header, footer
    function prepare_other_template() {
        $data['header'] = $this->CI->load->view('path/to/header/file', '', TRUE);
        $data['footer'] = $this->CI->load->view('path/to/footer/file', '', TRUE);
        $this->CI->load->vars($data);
    }

}

Then, in your controller, you just call:
Code:
$this->layout->prepare_template();

from any function or the constructor to cover all functions.

El Forum

[eluser]Drarok[/eluser]
Thanks for the replies, but I'd already looked at the FAQ, and the Layout library approach still requires me to have a repeated line in every controller (or individual functions).

Instead of an opt-in header/footer, I want an opt-out, so that the header/footer are always automatically included...

El Forum

[eluser]coolfactor[/eluser]
Another approach (the one that I use):

1. have a MY_Controller that the rest of your controllers extend from (rather than Controller)
2. have a loadView() function in MY_Controller that assigns the common header/footer
3. call $this->loadView() instead of $this->load->view(), which calls that for you

With this approach, you can override the loadView() function in any of your controllers to use a different header/footer, if you wanted.

Code:
class MY_Controller extends Controller
{

    function loadView($tpl, $data = array(), $return = TRUE)  // same prototype as $this->load->view()
    {
        // load header and footer sub-views
        $data['header'] = $this->load->view('header', $data, TRUE);
        $data['footer'] = $this->load->view('footer', $data, TRUE);
        // load the main view
        $this->load->view($tpl, $data);
    }

}

In your page controller, which is extending from MY_Controller:
Code:
class Sample extends MY_Controller {

    function index()
    {
        $this->loadView('sample');    // call replacement function
    }

}

El Forum

[eluser]Colin Williams[/eluser]
Still, he can't opt-out with that approach, but it's a good start I suppose.

El Forum

[eluser]Drarok[/eluser]
Correct me if I'm wrong, but it appears that even with that approach, I have to have <?=$header?> in my views?

El Forum

[eluser]thurting[/eluser]
I responded to a similar post with a solution that emulates rails behavior. Search for it.

It is a hook that allows for layouts or default CI behavior but it can be easily modified to force layouts.

El Forum

[eluser]esra[/eluser]
[quote author="Drarok" date="1186893237"]Correct me if I'm wrong, but it appears that even with that approach, I have to have <?=$header?> in my views?[/quote]

Coolfactor's approach is based on his proposed View library for CI. It is possible to create a single template-like file that includes a hard-coded header and footer and then use something like <?=$content?> for displaying different views or multiple views from your modules. If you need to use alternate headers and footers in some cases, it is possible to use different templates.

The View library can be extended like any other library and the methods can be overloaded as necessary. It might be possible to adapt a subclassed version of the View library to support xml-like namespaces for a XHTML-specific extension and it would give you a cleaner look. The namespace could support something like an include attribute. For example, <ci:include part="header" />, <ci:include part="content" />, <ci:include part="footer" />.

Using all of the View library approaches seen so far, there needs to be a way of including headers, footer or other blocks using variable substitution or some hard-coded approach.

El Forum

[eluser]Eric Barnes[/eluser]
Here is a link to a quick write up of how I accomplish a default "layout" view file.
http://www.ericlbarnes.com/2006/12/07/co...-tutorial/

Maybe it will help. Maybe not. Smile
Pages: 1 2 3