July 6, 2008 | In: PHP
CodeIgniter and Smarty
I’ve been used to working on projects using Smarty, its flexibility and most of the HTML designers and graphics artists I have worked with are only familiar with it. Until recently I was compelled by my co-worker to use a framework and he started using CodeIgniter without our prior approval and knowledge. To save time, I have to deal with it and continue with the CI path. Fortunately, CI can be simply extended from its Models, Controllers, libraries even its core files so it was not a big deal tying Smarty and CI together. This is how we do it.
According to the CI User Guide -> Creating Libraries, you can create your own library or extend/replace an existing native CI library. So far we need to create our own and extend from Smarty. SO in our application folder we add our Smarty library like shown in the folder structure below:
+/system
|
+----/application
|
+----/libraries
|
+----/smarty
| |
| +----/internals
| +----/plugins
| +----/Config_File.class.php
| +----/debug.tpl
| +----/Smarty.class.php
| +----/Smarty_Compile.class.php
+----/JHSmarty.php
+----/JHController.php
The above tree is only the part we are concerned, tying up Smarty with CI using libraries. You will notice two additional files, JHSmarty.php and JHController.php. Let us deal with JHSmarty.php first.
JHSmarty.php will serve as you CI custom library, it will extend the original Smarty class and we will add some additional functions for more flexibility. Consider the following example JHSmarty.php file.
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
require_once "smarty/Smarty.class.php";
class JHSmarty extends Smarty
{
public $CI = null;
public function __construct()
{
parent::Smarty();
}
public function view($resource_name, $cache_id = null) {
if (strpos($resource_name, '.') === false) {
$resource_name .= '.tpl';
}
return parent::display($resource_name, $cache_id);
}
public public function register_ci()
{
$this->CI =& get_instance();
}
}
?>
Now to breakdown each component:
__construct : As any PHP class we need a constructor, in this case we as well initialize our parent class by calling parent::Smarty();.
view : This is a simple implementation of the Smarty::display() function wherein we can optinally pass only the name part of a template file without the “.tpl” extension. This can be useful if you are presenting static pages self contained on a template.
register_ci : This function registers an instance of the CI base object into Smarty, meaning including all methods, variables and objects that you will normally find in your controller. Except in this case when you call the function the CI instance will be available as i.e. $this->CI->load->model('Somemodel','somemodel');. This is very useful if you are adding custom modifiers, plugins, etc to Smarty and you want to tap into existing resources in the CI object. Since smarty will pass itself to any plugin, modifier or outputfilter you can access it like this from any of them:
$smarty->CI->load->model('Somemodel','somemodel');
Also, you might want to autoload you JHSmarty library as you will be using your templating engine all through out your project. To automatically load your library just add the class name in all lowercase to your /system/application/config/autoload.php
$autoload['libraries'] = array('jhsmarty');
So in your controller you can always reference your custom library as:
$this->jhsmarty
Now, let’s go to the next file, JHController.php. The file is an extension of the native Controller class that comes with CI. Why would I need one? Simply because I need to control some aspects of my site on the Controller level i.e. Auth checking, loading global variables, etc.
One important note is, the JH prefix on the controller name (JH on the smarty library does not count I just used it for consistency). You must define your subclass prefix for CI to use them, /system/application/config/config.php contains the relative configuration.
$config['subclass_prefix'] = 'JH';
So what do I have on my extended Controller:
The defaultview variable : Since my extended native controller will be used on all further controllers within my project, I can use this variable to assign the template I will be using to display the current request.
The finalize method : This method will serve as my Smarty::display() version except that I can assign as much variables and control the further display of the defaultview variable. I can also trap errors and display an error page if needed.
I hope you find this article useful, mainly I wrote this for a new programmer I am working with. If you have any questions/comments feel free to drop a comment below.