Jens Segers on Jun 09 2011

CodeIgniter template library

Codeigniter has no functionality for handling multiple views/themes/layouts. This gives the developer a lot of freedom to choose what template library he wants to use, but some may find this a bit of a struggle. I have been making my own template systems for a long time now and still found myself changing it over and over again. So I sat down and rethought my current system and transformed it into something really good.

This template library for Codeigniter lets you build complex templates using partial views and widgets. It's built with the same method chaining support that we are seeing so often in Codeigniter so it feels familiar. This library loads a layout file that uses partial views. These partial view sections are internally represented by Partial Objects managed by the template library. These objects let you modify their content in a user friendly way through method chaining.

Installation

  1. Download the source from github: https://github.com/jenssegers/CodeIgniter-Template-Library
  2. Copy the files to the corresponding folder in your application folder.

I included some examples on github's repository. So if anything seems unclear, go take a look.

Initializing the library

Like most other libraries in CodeIgniter, the template library is initialized in your controller using the $this->load->library function:

$this->load->library('template');

You can also autoload the library.

Configuration options

Preferences are set by passing an array of preference values to the initialize function. Here is an example of how you might set some preferences:

$config["parser"]   = FALSE;
$config["template"] = "template";
$config["ttl"]      = 0;

$this->template->initialize($config);

Note: Most of the preferences have default values that will be used if you do not set them.

If you prefer not to set preferences using the above method, you can instead edit the config file. You will NOT need to use the $this->template->initialize() function if you save your preferences in the config file found in application/config/template.php.

  • $config["parser"] - if you want your template file to be parsed, set to TRUE
  • $config["template"] - the filename of the default template file
  • $config["ttl"] - the time all partials should be cache in seconds, 0 means no global caching

Template files

Template files are loaded or parsed by Codeigniter and the partials are passed to them as data. You can easily load them like you would normally use data in your view files:

<html>
    <head>
        <title><?php echo $title; ?></title>
        <?php echo $stylesheet; ?>
    </head>
    <body>
        <?php echo $content; ?>
    </body>
</html>

Or when parsing is enabled you can use {content} etc.

However, I prefer to directly call the library's methods from inside the template file to work around php's Undefined variable errors when you are not setting all partials. Calling these methods well replace non-existing partials with empty one's so you don't get any errors:

<html>
    <head>
        <title><?php echo $this->template->title; ?></title>
        <?php echo $this->template->stylesheet; ?>
    </head>
    <body>
        <?php echo $this->template->content; ?>
    </body>
</html>

These variables are in fact Partial Ojects, so you can still manipulate them from inside the template view file like this:

<?php echo $title->prepend("My Website - "); ?>

Partial manipulation methods will always return the partial object itself for further chaining or for displaying. So this is perfectly possible:

<?php echo $sidebar->cache(500)->prepend("Login: ")->widget("login"); ?>

Partial manipulation

Partials have a few handy methods for manipulating their content such as:

  • $partial->set() - overwrites the content
  • $partial->append() - append something
  • $partial->add() - same as append (alias)
  • $partial->prepend() - prepend something
  • $partial->content() - gets the content
  • $partial->default() - only set content if empty

You can also load dynamic content inside partials from view files or widgets. The object named partial used in the method chaining below is the name of the partial you want to load the content into.

$this->template->partial->view()

Append or overwrite the partial with a view file with parameters.

$this->template->partial->view("partial-name", array(), $overwrite=FALSE);

$this->template->partial->parse()

Append or overwrite the partial with a parsed view file with parameters.

$this->template->partial->parse("partial-name", array(), $overwrite=FALSE);

$this->template->partial->widget()

Append or overwrite the partial with a widget's output.

$this->template->partial->widget("widget-name", array(), $overwrite=FALSE);

Publishing

The template class only has a few methods. I chose to do this because almost everything can be managed by using the flexible Partial Object. If you want to publish the entire template with the current partials to the output you can use the publish() method.

You can pass a custom layout file and optional data if wanted:

$this->template->publish("layout", array("title"=>"Title is overwritten!"));

Most of the time this will be empty using the layout file from the config:

$this->template->publish();

If you wish to set the template file before publishing, eg. in a controller's constructor:

$this->template->set_template("template2");

Triggers

Some partials have built in triggers:

  • stylesheet - you only need to pass the source
  • javascript - you only need to pass the source
  • meta - will convert the arguments to the right meta tag
  • title - converts special characters
  • description - will convert special characters just like the title

This is an example of what these built in triggers do:

$this->template->stylesheet->add("stylesheet.css", "all");
// <link rel="stylesheet" href="http://myweb.com/stylesheet.css" media="all" />

$this->template->javascript->add("script.js");
// <script src="http://myweb.com/script.js"></script>

$this->template->meta->add("robots", "index,follow");
// <meta name="robots" content="index,follow" />

$this->template->title->set("Dad & Son");
// Dad & Son

You can set your own triggers for functions or methods for any partial object like this:

// function
$this->template->partial->bind("strtoupper");

// method
$this->template->partial->bind($this->typography, "auto_typography");

This will trigger the function or method whenever you manipulate the partial's content.

Widgets

Widgets are intelligent partial objects. When their content is asked, their display() method is activated which will fill the content using codeigniter or partial object methods. Widgets classes are found inside the application/widgets folder. They extend the main Widget class which has the same methods as the Partial class. This is an example widget:

/* File: widgets/hero_widget.php */
class hero_widget extends Widget {
     public function display($args = array()) {
         $this->load->model("my_model");
         $data = $this->my_model->all();

         $this->load->view("widgets/hero", $data);
     }
} 

And this is loaded from a controller like this:

$this->template->partial->widget("hero_widget", $args = array());

Caching

I did not want to expand the library in all different ways, therefore I implemented a basic caching function using Codeigniter's caching driver. This might slow your code down on simple websites but allows you to use caching for partials just like you would do yourself with Codeigniter's driver.

You can cache particular partials:

$this->template->partial->cache(100);

Or you can cache all partials:

$this->template->cache(100);

Both methods have an extra optional identification parameter that you can use to have multiple cache files for different pages:

$this->template->cache(100, "frontpage");

Conclusion

This template library offers you more flexibility than most other libraries, as result of the partial objects that represent partial view sections that make manipulation trough method chaining so easy. Because everything is managed trough partial objects, you don't need to memorise a whole bunch of template methods because there aren't any!

If you have tips or suggestions, feel free to contact me or leave a message below.


Comments

Greneda 2 months ago

Good tutorial...


samueyes 3 years ago

support for ci ver. 3 ?


Markus 4 years ago

Hi Jens, what about SSL? If i was on a SSL page and include a js like: $this->template->javascript->add(ASSETSPATH."js/customers.js", "all"); The absolute path that was builded is:

But i need it like:

Could you please hlep me?

Kind regards Markus


Anas 5 years ago

Hi, I'd really love to use your lib.

But seems like it does not support custom file/folder structure on projects with HMVC.

I put my themes in Application/Themes. For a theme called MyTheme, the default layout file would be Application/Themes/MyTheme/Views/Layouts/default.php

It's a pity that you've made an excellent HMVC library, but your template library couldnt complement it's capability.


Antonio Vizuete 6 years ago

Hi Jens! Congrats for this great job! It's very helpful for me. Thanks. Rergards form Spain.


vincenzo 6 years ago

i have ci 2.0 with hmvc setup thanks to wirez design. i'd like to have the theme in a folder like theme/mytheme/template.php instead of view/template.php. Is possibile with your library?