4. Showing Your Work

Now that you have total control of how the application handles the user’s request, it’s time to look at how you present information to the user.

View Basics

Code which controls how CodeIgniter presents information to the browser is usually stored in view files. Views are simply PHP files that contain the HTML you want to display to your user.

They are stored (by default) in the /application/views directory.

Views are loaded with the $this->load->view() command. The first parameter is the name of the view to display.

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

This displays the view located at /application/views/welcome_message.php.

You could easily store that view under a sub-directory for each part of the application, allowing you to split out admin views from app views, or views used by different controllers. Just add the name of the sub-directory to the name of the view.

$this->load->view('admin/welcome_message');

This would display the view located at /application/views/admin/welcome_message.php.

View Data

You can make data available to use within the view by passing it in as the second parameter. This should be an array of key/value pairs.

1 $data = array(
2 	'user_name' => $username
3 );
4 $this->load->view('welcome_message', $data);

In the view, you would access this data as a variable named after the key of the array.

<?= $user_name ?>

If you pass an array or an object in as one of the values, you have full access to that object or array within the view.

// In the controller:
$user = array(
	'first_name' => 'Darth',
	'last_name' => 'Vader'
);
$this->load->view('profiles/basic_info', array('user' => $user));

// In the view:
<h2>Welcome back, <?= $user['first_name'] .' '. $user['last_name'] ?>!</h2>

To keep things organized, and easier to use in a mixed AJAX/non-AJAX request-based controller, you might find it works best to split out parts of your data into different class methods, or into libraries. This makes it simple to pull the information together in the controller.

1 $data = array(
2 	'user' => $this->auth_lib->current_user(),
3 	'profile' => $this->collect_profile_info($this->auth_lib->id())
4 );
5 $this->load->view('profiles/basic_info', $data);

There are times, though, when you need to add items to the view from locations other than your controller, or maybe you want to make some variables available from within your controller’s constructor. No problem. You can add data to be displayed in the view from any place that has access to the controller instance with the $this->load->vars() method.

1 $data = array(
2 	'current_user' => $this->auth->current_user(),
3 	'user_theme' => $this->user_model->get_user_theme()
4 );
5 $this->load->vars($data);

This is similar to using the second parameter of the $this->load->view() method, but can be called multiple times from different locations before loading the view. If keys in the data passed to either $this->load->vars() or $this->load->view() match, the later value(s) will replace the previous value(s).

Constructing Pages

What you want to display to the user, though, is typically not just a single view. There will be common elements, like page headers, footers, and sidebars, that need to wrap around the content. There are a few ways that you’ll see mentioned in the forums, but I’ve never found any of them to be robust enough for my needs in a world where clients like to change their minds all too often.

I will go over them here, because for some very simple sites they may be all that’s needed. With each method I go over, you’ll notice things get abstracted more and more until it becomes a simple theme system that works with you to keep your code organized in a way that can be understood by anyone on the team.

Method 1: In Method

The first method I saw recommended years ago, which is fine for small brochure-type sites, is to load all of the views in sequence:

 1 public function index()
 2 {
 3 	// Make all of the data available for all views...
 4 	$this->load->vars($this->data);
 5 
 6 	$this->load->view('header');
 7 	$this->load->view('site_navigation');
 8 	$this->load->view('the_actual_page_content');
 9 	$this->load->view('footer');
10 }

While this works, it becomes tedious if you have to do that in every controller method which needs to display something to the user.

Method 2: In View

The next most common method I’ve seen used in a couple of different CMSs, is to load views at the top and bottom of each view. This allows several other views to be grouped in one file, like a header file that calls the HTML head view, a view that contains the page header, and the main navigation, and perhaps even the sidebar. Then a second footer view might include the page footer, another view to collect and output JavaScript, etc.

// In the controller
$this->load->view('the_contents');

// In "the_contents" view
$this->load->view('theme/header_collection');

page content goes here...

$this->load->view('theme/footer_collection');

This reduces a lot of our calls by combining the different elements into collections of templated content which surrounds our page content. Then, if anything needs to change in the template, you can simply alter those template views and your entire site is updated. For many small sites, this can work just fine. However, once the number of pages you need to display grows, this becomes a bit burdensome.

There’s a better way, based around some conventions that help keep your code organized, and give you the ability to swap out themes at will, even using different themes per controller, or method, all while reducing the amount of work you have to do while building the site. This is a simplified version of what I tend to use now, and is very close to a version I’ve used on quite a few different sites. That’s what this next section is all about.