Usually, when I want to output something to the browser, I simply do a $this->load->view(‘the_view’, $data); and that’s it. Inside the the_view.php I also load the parts that stay unchanged, like the header and footer, with the same $this->load->view(‘the_header’); and $this->load->view(‘the_footer’). But, that is a repetition in itself, isn’t it?

So why not, instead of using $this->load->view… we only call a rendering function that will apply the master template to the specific view/content requested by a method ? Being something that will be repeated across a lot of methods, we will define the rendering function inside the MY_Controller. We will take over the code from our previous step and work on it:

application/core/MY_Controller.php

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?phpdefined('BASEPATH')ORexit('No direct script access allowed');

classMY_ControllerextendsCI_Controller

{

protected$data=array();

function__construct()

{

parent::__construct();

$this->data['pagetitle']='My CodeIgniter App';

}

protectedfunctionrender()

{

$this->load->view('templates/master_view',$this->data);

}

}

Now, that we’ve asked for it, let’s create the master_view.php. As you can see we ask the the view from the templates folder, which will have to be created inside the views directory.

Let’s look in the views directory:

INI

1

2

3

4

-application/

--views/

---errors/

---welcome_message.php

As you can see, there are a lot of “errors” in there. Those files belong to the CodeIgniter and are served when an error appear inside our app. Of course, you can change their look.

In there we also see the welcome_message.php which also comes with the framework, being served by the default controller.

Inside views directory let’s create a directory named templates and inside the templates we will create master_view.php. For the moment, we will create a basic html structure:

application/views/templates/master_view.php

XHTML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type"content="text/html; charset=UTF-8" />

<title>My CodeIgniter App</title>

</head>

<body>

<header>

<nav>

<ul>

<li>My menu item</li>

</ul>

</nav>

</header>

<section>

<p>Here is where i will put the text</p>

</section>

<aside>

<p>Here is a sidebar</p>

</aside>

<footer>

<p>Copyright 2009 My CodeIgniter app</p>

</footer>

</body>

</html>

If we did everything right we should see our page if we visit http://localhost/

Now we have to optimise the code.

So let’s separate header, sidebar and footer from our master_view.php. To do this we will create a directory inside templates named _parts and the files inside the _parts will be:

master_header_view.php:

application/views/templates/_parts/master_header_view.php

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type"content="text/html; charset=UTF-8"/>

<title>My CodeIgniter App</title>

</head>

<body>

<header>

<nav>

<ul>

<li>My menu item</li>

</ul>

</nav>

</header>

master_sidebar_view.php:

application/views/templates/_parts/master_sidebar_view.php

PHP

1

2

3

<aside>

<p>Here isasidebar</p>

</aside>

master_footer_view.php:

application/views/templates/_parts/master_footer.view.php

PHP

1

2

3

4

5

<footer>

<p>Copyright2009My CodeIgniter app</p>

</footer>

</body>

</html>

Now, the master_view.php will look like:

application/views/templates/master_view.php

PHP

1

2

3

<section>

<p>Here iswhereIwill put the text</p>

</section>

But we need to append those header, sidebar and footer views to the master view:

application/views/templates/master_view.php

PHP

1

2

3

4

5

6

7

8

9

10

<?php

$this->load->view('templates/_parts/master_header_view');

?>

<section>

<p>HereiswhereIwillputthetext</p>

</section>

<?php

$this->load->view('templates/_parts/master_sidebar_view');

$this->load->view(templates/_parts/'master_footer_view');

?>

Now, on the render method we request for the master template:

PHP

1

2

3

4

protectedfunctionrender()

{

$this->load->view('templates/master_view',$this->data);

}

Apply the master template to pages

Well… we rendered the master template, but where will the content of pages fit into this? Let’s pass the page’s view as parameter to the render method:

The $the_view variable should contain a view that is particular to the controller’s method. So let’s create one named homepage_view.php:

application/views/homepage_view.php

XHTML

1

2

3

<h1>Hello from homepage</h1>

<p>testing homepage view</p>

Now we have to change the master_view.php a bit to insert the page view:

application/views/templates/master_view.php

PHP

1

2

3

4

5

6

7

8

9

10

<?php

$this->load->view('templates/_parts/master_header_view');

?>

<section>

<?phpecho$the_view_content;?>

</section>

<?php

$this->load->view('templates/_parts/master_sidebar_view');

$this->load->view('templates/_parts/master_footer_view');

?>

Using more than one template?

Now, let’s put this into perspective. What if our site will use two or more templates. Let’s say, we have a one column template for static pages and two column template for posts? Then we can change the render() method to receive another parameter that will decide what template will be used:

The page title…

In the header we have the title tag. We already defined the generic title in the MY_Controller class, so why not replace the hard-coded title with the generic title:

XHTML

1

<title><?phpecho$pagetitle;?></title>

Return JSON instead of a page? Why not?

I don’t know if this can be part of this specific step, but why not allow the render method to decide if it returns a html page or a JSON string. Until I decide if this will be a new step let’s modify the render() method a bit:

33 thoughts on “Step 12 – Creating and using page templates in CodeIgniter”

Thank you for such awesome tutorials on Codeignitor 3, I am busy learning Codeignitor and rewriting the above site. I had started with Codeignitor 2.2 but am now trying to convert it to the new version. Once again thank you so much for sharing your knowledge about the new version.

I wouldn’t know what to say, as nowhere in my tutorial am I talking about $this->data[‘content’]. I am talking about $this->data[‘the_view_content’] (or did I miss something and I don’t see it?)… Anyway, I would need more details regarding your script.

Great tutorial…as usual.
I’m interested in learning more about
if($template == ‘json’ || $this->input->is_ajax_request()) { header(‘Content-Type: application/json’); echo json_encode($this->data); }
Adrian, do you think it would be possible to have a tutorial about this?
Thanks

I’m trying to add AJAX funcionality using your great render system. I’d like to use AJAX pagination to scroll a table with more then 10.000 row and I’m trying to use the following library: http://www.codexworld.com/ajax-pagination-in-codeigniter-framework/#comment-11900
To draw the table I thought to load the view without a template, so, following your instruction in the section above rendering the table with:
$this->render(‘admin/registrations/table_registrations_view’,NULL);
But I got no data in page 🙁
Any hint?

Loving the tutorials, I have implemented this template system on a few projects of mine now but was just wondering if there was a way of passing data from the controller to the view whilst still using render()?

I have tried previously and am sure it might be me missing something but any help you have to offer on the matter would be greatly appreciated! 🙂

When I have been using $this->load->view(‘view_path’, $data); and then having variables such as $data[‘stuff’] = “stuff”; it works fine but as soon as I try to access those variables using render instead of view it throws errors saying the variables do not exist. I am also making sure that they are arrays to pass. Am I missing something?

Well… If you want to use the render() method, you must define the variables as $this->data (and not $data), because $this->data is actually a property defined and used in MY_Controller, and not merely a variable of your controllers.

Ahhhhh, Thanks so much, I knew it was something simple I was missing but just couldn’t see what and now I look back into my controller I can see previous times I have done it correctly with $this->data instead. *slaps hands on head*

I have learned many things about codeigniter on your blog following these tutorials and i want to thank you.I also see that you ran out of ideas for new tutorials as you stated.Well perhaps you could expand your authentication system series with “Logging user out on browser close”.I use this config and have no clue on how to do that :
$config[‘sess_driver’] = ‘database’;
$config[‘sess_cookie_name’] = ‘ci_session’;
$config[‘sess_expiration’] = 7200;
$config[‘sess_save_path’] = ‘ci_sessions’;
$config[‘sess_match_ip’] = FALSE;
$config[‘sess_time_to_update’] = 300;
$config[‘sess_regenerate_destroy’] = FALSE;

Strange but that didn’t work for me yesterday before i posted a question here.Then i went on googling about it and found people saying something that ‘sess_expiration’ set to 0 creates a cookie that lasts 2 years instead of doing what is supposed to do.I didn’t check if the cookie was set in my browser and now i am more confused on what happened over night 🙂 .However, everything works well now.Thank you for reply and i hope you get new ideas soon.This blog is awesome