How I do layouts and views in CodeIgniter

I have been a loyal fan of the kick-ass php framework, codeIgniter, for some time now. A while back I made a post on how to improve the view handling of codeIgniter. I would like to retract that post. Through the comments on that post I found out about an undocumented parameter (as of version 1.7, it has been documented) that allows view to be rendered into a variable. This changes everything, and totally negates any of the complaint I had about how CI handles layouts and views.

Below is an example of live code I have running at loudsongs.com. It shows how I have been able to take advantage of of this powerful third parameter that stops CI from rendering a view to the screen when loading it.


Inside of my controller

function index()
 {
 $base_url = base_url();

//what the nav needs
 $navigation_data['navTab'] = "home";

//basic info for the header
 $layout_data['pageTitle'] = "LoudSon.gs";
 $layout_data['meta_description'] = "Under Ground Lyrics, hardcore, metal, emo, rock";
 $layout_data['meta_keywords'] = "lyrics,song,songs,words,hardore,metal,emo,rock";
 $layout_data['meta_url'] = "$base_url";
 $layout_data['meta_classification'] = "home";
 $layout_data['searchInput'] = "";
 $layout_data['searchOptions'] = "";

$this->load->model('search');
 $lastest_albums = $this->search->last_n_albumsAdded(10);
 $popular_songs = $this->search->popular_n_songs(10);

//get the featured Albums
 $featuredAlbums = $this->search->getFeaturedAlbums();

$body_data['featured'] = $featuredAlbums;
 $body_data['newest'] = $lastest_albums;
 $body_data['popular'] = $popular_songs;

//load the content variables
 $layout_data['content_navigation'] = $this->load->view('navigation', $navigation_data, true);
 $layout_data['content_body'] = $this->load->view('home/homePage', $body_data, true);

$this->load->view('layouts/main', $layout_data);
 }

/views/navigation.php

<div id="header">
 <h1 title="Loud Songs Logo">LoudSongs search - hard to find obscure lyrics</h1>

<ul title="navigation">
 <li <? if($navTab == "about"){echo " id=\"active\"";}?>><a href="<?= base_url(); ?>about" title="About Page">About</a></li>
 <li <? if($navTab == "add"){echo " id=\"active\"";}?>><a href="<?= base_url(); ?>add" title="Add Lyrics">Add Lyrics</a></li>
 <li <? if($navTab == "home"){echo " id=\"active\"";}?>><a href="<?= base_url(); ?>" title="Home Page">Home</a></li>
 </ul>
 </div>

/views/home/homePage.php

<div>
 Thanks for visiting LoudSongs
 <br/>
 We are trying to build a maintain a collection of punk rock, hardcore, emo, metal and other lyrics.
 This website is free and open to all.
 Please help us by <a href="http://www.LoudSon.gs/add">contributing to the collection</a>.
 </div>

<div>
 <? $this->load->view('home/featuredAlbums'); ?>
 </div>

<div class="middle_col_split">
 <? $this->load->view('home/recentlyAdded'); ?>
 </div>

<div class="middle_col_split">
 <? $this->load->view('home/mostPopularSongs'); ?>
 </div>

/views/layouts/main.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html;charset=us-ascii">
 <meta name="description" content="<?= $meta_description ?>">
 <meta name="keywords" content="<?= $meta_keywords ?>">
 <meta http-equiv="expires" content="0" />
 <meta name="classification" content="<?= $meta_classification ?>" />
 <meta name="Robots" content="index,follow">
 <meta name="revisit-after" content="2 Days">
 <meta name="language" content="en-us">

<link href="<?= base_url() ?>includes/styles/lyrics.css" rel="stylesheet" type="text/css" media="screen" title="default">

<script language="javascript" type="text/javascript" src="<?= base_url() ?>includes/scripts/jquery-1.2.6.min.js"></script>

<title><?= $pageTitle ?></title>
 </head>

<body id="home">
 <div id="nav">
 <?= $content_navigation; ?>
 </div>

<div id="middle_column">

<?= $content_body ?>

</div>
 </body>

</html>


wow, ok, so that might be a lot to digest. The bottom line is this, CI doesnt have “layouts” like other frameworks, so you have to become creative and use a view AS a layout by using the mythical 3rd parameter when loading a view. We load data into the navigation view and store all of that into the $layout_data array, then we load a view named homePage and pass data into it, and stor it into the $layout_data array. When we are done loading all of the views into the array, we pass that array into another view. This view acts as our layout. easy as that! check it out below:

//load the content variables
 $layout_data['content_navigation'] = $this->load->view('navigation', $navigation_data, true);
 $layout_data['content_body'] = $this->load->view('home/homePage', $body_data, true);

$this->load->view('layouts/main', $layout_data);

I hope this helps someone understand how codeigniter does have layout and view functionality, you just have to structure it that way in your code.

post some comments if you need more clarification.