Skip to content

Displaying Multiple Views

Derek Jones edited this page Jul 5, 2012 · 21 revisions

Category:Help::Views | Category:Help::TipsAndTricks NOTE: This article was written before version 1.6. Version 1.6 of CI allows multiple views to be loaded in same controller function.

Introduction

When you try and load more than one View (for whatever reason) in one function, you see that it simply just won't work. There are a bunch of ways to do this

See also Displaying Multiple Templates

Method 1 - Concatenating views

This method combines the output of all your views sequentially, so for example, you might have a view that sets up your headers, then your content, then your footers.

Find your function (or functions) where you have more than one view call ($this->load->view('', '', '');), and replace them with:

$output  = $this->load->view('your_view', 'your_data', true);
$output .= $this->load->view('your_other_view', 'your_other_data', true);
$output .= $this->load->view('your_last_view', 'your_last_data', true);

$this->output->set_output($output);

As you can see, all the View calls are assigned to the $output variable. Also, every View call must have that last bit of TRUE at the end, like so:

Correct:

$output  = $this->load->view('your_view', 'your_data', true);
$output .= $this->load->view('your_other_view', 'your_other_data', true);
$output .= $this->load->view('your_last_view', 'your_last_data', true);

$this->output->set_output($output);

Incorrect:

$output  = $this->load->view('your_view', 'your_data');
$output .= $this->load->view('your_other_view', 'your_other_data');
$output .= $this->load->view('your_last_view', 'your_last_data');

$this->output->set_output($output);

Also, the first View call must have php $output = before it. Then the View calls after the first one, have to have ```php $output .=


You can also, alternatively, pass the $output variable to the Output Class that CodeIgniter has (for caching or things like that), like so:

```php
$output  = $this->load->view('your_view', 'your_data', true);
$output .= $this->load->view('your_other_view', 'your_other_data', true);
$output .= $this->load->view('your_last_view', 'your_last_data', true);

$this->output->set_output($output);

... your output parsing, caching, etc code here ...

Method 2 - Embedding views

This method embeds a view within another view.

You can have a view that formats a menu, one that displays the contents of an article, and one that contains the overall template.

views/menu.php:

<ul>
&lt;?php foreach ($items as $url=>$item) {
   echo '<li><a href="'.$url.'">'.$item.'</a></li>';
}
?&gt;
</ul>

views/article.php:

<div id="article">
<h1>&lt;?= $title ?&gt;</h1>
<span class="date">&lt;?= $date ?&gt;</span>
<span class="author">&lt;?= $author ?&gt;</span>
<p>&lt;?php echo nl2br( str_replace("\n\n","</p><p>", $body )); ?&gt;</p>
</div>

views/maintemplate.php:

&lt;html&gt;
&lt;head&gt;
&lt;title&gt;&lt;?= $title ?&gt; - My Site&lt;/title&gt;
&lt;link rel="stylesheet" type="text/css" href="/css/main.css" /&gt;
&lt;/head&gt;
&lt;body&gt;
   <div id="wrapper">
      <div id="header">My Embedded-View Site</div>
      <div id="menu">&lt;?= $menu ?&gt;</div>
      <div id="content">&lt;?= $content ?&gt;</div>
      <div id="footer">&copy; 2006&lt;?php $endyear = date("Y"); if ($endyear != 2006) echo '-'.$endyear; ?&gt; Me</div>
   </div>
&lt;/body&gt;
&lt;/html&gt;

To use this in your controller (let's pretend $row is the contents of some article pulled from a database):

$menu['items'] = array("/articles" => "Articles", "/authors" => "Authors");

$template['title'] = $row['title'];
$template['menu'] = $this->load->view('menu', $menu, true);
$article['title'] = $row['title'];
$article['author'] = $row['author'];
$article['date'] = $row['date'];
$article['body'] = $row['body_text'];
$template['content'] = $this->load->view('article', $article, true);

$this->load->view('maintemplate', $template);

How this works is the first two views return output, which is added to our $template array. This array is then passed to the final template, where all the rendering happens.

The benefit of this over method #1 above is that each view contains a more-or-less standalone and relevant chunk of HTML (ie, you don't need a seperate header and footer that have <body> and </body>, respectively). This makes adding things like the wrapper

much easier, as there's only one file to edit, and thus minimizes the possibility of unmatched elements and other HTML errors. To make things even easier to read, you can put HTML comments in your views at the start and end, like <!-- START of menu view -->. When debugging, these will make the resulting HTML very simple to read.
Clone this wiki locally