73

I'm starting a large codeigniter project and would like to try to create some reusable 'mini' views for snippets of content like loops of data which may be displayed on different pages/controllers.

Is it better to call the views from within the main controller's view? If so, how? Or should I call the 'mini view' from the controller and thus pass the view's code to the main view?

1

6 Answers 6

126

Views within other views are called Nested views. There are two ways of including nested views in CodeIgniter:

1. Load a nested view inside the controller

Load the view in advance and pass to the other view. First put this in the controller:

<?php
// the "TRUE" argument tells it to return the content, rather than display it immediately
$data['menu'] = $this->load->view('menu', NULL, TRUE);
$this->load->view ('home', $data);
?>

Then put <?=$menu?> in your view at the point you want the menu to appear.

2. Load a view "from within" a view

First put this in the controller:

<?php
  $this->load->view('home');
?>

Then put this in the /application/views/home.php view:

<?php $this->view('menu'); ?>

<p>Other home content...</p>

About best method, I prefer the 1st method over 2nd one, because by using 1st method I don't have to mix up code, it is not like include php. Although indirectly both are same, the 1st method is clearer & cleaner than 2nd one!

8
  • I think there is no need to Load view in advance and pass to the other view.see my solution Commented Mar 5, 2013 at 11:36
  • 1
    @RahulChipad you did'nt noticed the comment : the "TRUE" argument tells it to return the content, rather than display it immediately which means it will not affect at all even it is loaded in advance
    – sandip
    Commented Mar 5, 2013 at 11:44
  • 4
    WARNING: When you pass a view this way (with the TRUE parameter ) you are converting all your view content into a string. This works most of the time, but once you have heavy data, or perhaps when you are passing arrays or JSON, this will break.
    – CodeGodie
    Commented Jul 21, 2015 at 21:27
  • 2
    I don't like method 1 because in the home view there is never a proper receiving of $menu ... if you were to look at home, you would no idea where $menu came from ...
    – dsdsdsdsd
    Commented Apr 5, 2016 at 3:19
  • 2
    2nd way is way more preferred Commented Mar 2, 2017 at 6:20
18

Honestly I prefer to do this by having template views then loading that with the necessary data from the controller, it means a lot less repeated code and follows the DRY concept better than loading views from views. Especially for things like headers, footers and menus.

So my template view would look something like this:

template.php

$this->load->view('header',$title);
$this->load->view('sidebar',$sidebar_content);
$this->load->view('main_content',$main_content);
$this->load->view('footer');

Then in my controller I pass the data required to the template like this:

$data['title'] = 'Home Page';
$data['sidebar_content']='pages/standard_sidebar';
$data['main_content'] ='pages/my_home_page'; 
$this->load->view('template',$data);

There are a number of benefits to doing it this way. First is I can have multiple templates, for example I have, in my case, two main ones, one for full page views without a sidebar and one for pages with a sidebar, I also call an if statement to decide which header to include, the regular one or the one with the admin menu in it.

Yes I could include the header, sidebar and footer in every main view page, but that ends up in a ton of duplicate code. And what happens if for example I want all my pages to have something new, some other small snippet? Using templates I add the snippet to the appropriate template and it's done. Going the other route I find every page and add the snippet view there, it's the equivalent to having CSS in the page in my opinion, wasteful and not ultimately maintainable.

6
  • 1
    I like your technique but I don't quite understand how the other methods increase coding effort. Say for example, if I want to add a language bar in the header view, I'd just edit the header view and nothing else. Am I missing something? BTW, I'm an old time coder who's totally new to CodeIgniter.
    – itsols
    Commented Feb 27, 2015 at 11:39
  • They don't increase coding effort as much as they increase duplicate code. Look at the code above. If I hadn't created a template then I'd be calling the first 4 lines for every page in my controller. It's more about modularity and ease of inclusion/exclusion than anything. On a very basic site where all the pages have the same elements it's not really that big a deal, or even really worth the added effort. On a complex site where the pages vary significantly it can save a lot of headache and duplication. Commented Feb 27, 2015 at 17:22
  • isn't this effectively the same as method 2 of @sandip's answer ??
    – dsdsdsdsd
    Commented Apr 5, 2016 at 3:22
  • My answer gave an alternative view to the same code and showed the benefits of splitting up into templates. The method of injecting it is the same, the overall view is not even close. 3 year old answer, does it really matter if two people give the same code with different viewpoints? Commented Apr 6, 2016 at 16:00
  • How can I pass $data to header? Let's say I want to pass more things to header than just $title Commented Mar 4, 2017 at 20:10
9

METHOD 1

I use this method into my view to insert the include view where I want

$this->load->view('include/include_view');


METHOD 2

or in the controller you can load more than a view like this:

$this->load->view('header_view');
$this->load->view('list_view');
$this->load->view('footer_view');

No one method is better than the other, it depends if you have to pass some data (in this case use method2) or if you want to include a view in a specific part of your main view (in this case is better to use method1)


METHOD 3

Passing data to your include view by your main view

into your controller:

$data['title'] = "Title";
$this->load->view('main_view',$data);

in your view

$data2['title'] = $title;
$this->load->view('include/include_view',$data2);

If you want to pass entire data to your include view you can do in this way: in your controller:

$data['nestedView']['title'] = 'title';

in your view

$this->load->view('includes/included_view', $nestedView);
3
  • I'll be looking to pass data, but method one seems to be a better idea. Just need to figure out how to pass data to it.
    – David
    Commented Mar 5, 2013 at 10:30
  • well you can pass data in this mode: $this->load->view('include/include_view',$data); but the problem is that in your controller you have to pass data to your main controller and in your main controller you have to pass data to your include view, is a long way but if you need this you can Commented Mar 5, 2013 at 10:35
  • is there a way to pass the entirety of the data?
    – David
    Commented Mar 5, 2013 at 10:55
4

This a simple way of including views within views.there is no need to load views in advance.just pass view path to other view.

In your controller use this:

$data['middle'] = 'includeFolder/include_template_view';  //the view you want to include
$this->load->view('main_template_view',$data);  //load your main view

and in main_template_view you can include other views :

$this->load->view($middle);
2

In my opinion for solve in more efficient way this problem I have done so:

You create a new helper (in application/helpers) with name (es. common_helpers.php, the underscore is important). In this file, you put all the functions for example build pieces of html in common.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

    function getHead(){
    require_once(APPPATH."views/common/head.php");
    }   

    function getScripts(){
    require_once(APPPATH."views/common/scripts.php");
    }

    function getFooter(){
    require_once(APPPATH."views/common/footer.php");
    }

In your controller you call only one view in respect of MVC and call the functions from your custom helper.

class Hello extends CI_Controller {

   public function index(){
       $this->load->helper('common');
       $this->load->view('index');   
   }

}
-1

In the controller

controller

<?php
    public function view($page = NULL)
        {
          if ( ! file_exists(APPPATH.'views/pages/'.$page.'.php'))
        {
                 $data['title'] = ucfirst($page); // Capitalize the first letter
                // Whoops, we don't have a page for that
                show_404();

        }

        $data= array(''); 
        $data['title'] = ucfirst($page); // Capitalize the first letter 
         $data['page_layout']='pages/'.$page;    
         $this->load->view('page_layout', $data);
        }
?>

In the Views folder create a page called page_layout.php

page_layout.php

//This is where you set the layout to call any view through a variable called $page_layout declared in the controller//

 <?php
     $this->load->view('header');
     $this->view($page_layout);
     $this->load->view('footer');
  ?>

Not the answer you're looking for? Browse other questions tagged or ask your own question.