CodeIgniter+Smarty - Perfect Together
If you are not familiar with CodeIgniter, it is a lightweight Model-View-Controller (MVC) framework written in PHP. It is an open source project maintained by EllisLabs. CodeIgniter has a templating system built in but, the last time I looked at it, it does not have many features. It also implements the templating by filtering the page using preg_match() and string replacement. For web sites with low traffic volumes and few variable replacements, this approach is fine. As the traffic volume picks up or with larger pages, this may impact the response time of the web site.
Smarty is another open source project that handles templates and is also written in PHP. It has been around for a while and has many features beyond the simple templating engine built into CodeIgniter. Smarty also "compiles" templates into pure PHP which makes them slightly faster to execute.
Templating is a controversial topic with some devlopers since they feel that using PHP directly in the HTML is easier than learning a new templating language to accomplish the same thing. I personally like having a clean separation between code (PHP) and views (templates using Smarty). I have seen too many developers get sloppy and start adding logic and even database calls in their HTML. This can quickly become a maintenance nightmare. I also like the fact that Smarty uses different delimiters {} from HTML <>. This makes spotting the Smarty tags easy. A simple example that illustrates this point is:
Using Smarty:
<title>{$title}</title>
Using PHP:
<title><?php echo $title;?></title>
One minor annoyance is that if you have curly braces in your HTML, like inline javascript or inline stylesheets, you need to escape them so they won't be interpreted as Smarty tags. To do this, surround the section you want to turn off Smarty with {literal} and {/literal}. Here is an example:
<script type="text/javascript">
{literal}
function a(b, c) {
alert('function a('+b+', '+c+') called!');
}
{/literal}
</script>
You can place {literal} and {/literal} anywhere even surrounding a single character. Hopefully you are using external javascript and stylesheet files so this escaping won't be necessary.
The next question you may have is "How do I use Smarty in CodeIgniter?". Well, I took some time to document how I did it and also give some code and examples to get you started.
Step 1) Install CodeIgniter
That is, if you haven't already installed it. You can download CodeIgniter here.
Step 2) Install Smarty
You can find the latest download for Smarty here. I created a directory called /system/libs/ in CodeIgniter and copied the smarty directory there. If you decide to install Smarty somewhere else, make sure you update the Smarty.php library module to point to your Smarty installation. The directory you point to should have the Smarty.class.php PHP class file in it.
Step 3) Create template directories
I created the templates directory (Smarty's root template directory) and templates_c directory (where the compiled versions of the Smarty templates reside) in /system/application/views. Again, if you decide to keep your templates elsewhere, be sure to update Smarty.php to point to your directories. Make sure the templates_c directory has write access for your application.
Step 4) Install the code from this site
The code from this site includes the Smarty library class that bridges between Smarty and CodeIgniter, A few Smarty plugins to help bridge access to CodeIgniter features, and a small demo called "example".
The main class (I know I am using the CI_ prefix instead of the MY_ prefix but no class called Smarty exists in CodeIgniter) is called CI_Smarty and can be added to the autoload config array as 'smarty'. It is a similar implementation to other ones out there. By extending the main Smarty class as a CodeIgniter library, you have access to all of the Smarty API calls. I added an extra function called smarty->view() as a convenience function which behaves as the parser->parse() functon from CodeIgniter's templating system. Further down I list Smarty plugins that bridge the gap between Smarty and the CodeIgniter libraries for those times you need access in the template. The ones I have included do not break the MVC paradigm, but rather make it easier to access language file data, validation errors, etc. instead of trying to stuff everything into the $data array before calling your template.
Here is the main Smarty library class:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Smarty Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Smarty
* @author Kepler Gelotte
* @link http://www.coolphptools.com/codeigniter-smarty
*/
require_once( BASEPATH.'libs/smarty/libs/Smarty.class.php' );
class CI_Smarty extends Smarty {
function CI_Smarty()
{
parent::Smarty();
$this->compile_dir = APPPATH . "views/templates_c";
$this->template_dir = APPPATH . "views/templates";
$this->assign( 'APPPATH', APPPATH );
$this->assign( 'BASEPATH', BASEPATH );
log_message('debug', "Smarty Class Initialized");
}
function __construct()
{
parent::__construct();
$this->compile_dir = APPPATH . "views/templates_c";
$this->template_dir = APPPATH . "views/templates";
$this->assign( 'APPPATH', APPPATH );
$this->assign( 'BASEPATH', BASEPATH );
// Assign CodeIgniter object by reference to CI
if ( method_exists( $this, 'assignByRef') )
{
$ci =& get_instance();
$this->assignByRef("ci", $ci);
}
log_message('debug', "Smarty Class Initialized");
}
/**
* Parse a template using the Smarty engine
*
* This is a convenience method that combines assign() and
* display() into one step.
*
* Values to assign are passed in an associative array of
* name => value pairs.
*
* If the output is to be returned as a string to the caller
* instead of being output, pass true as the third parameter.
*
* @access public
* @param string
* @param array
* @param bool
* @return string
*/
function view($template, $data = array(), $return = FALSE)
{
foreach ($data as $key => $val)
{
$this->assign($key, $val);
}
if ($return == FALSE)
{
$CI =& get_instance();
if (method_exists( $CI->output, 'set_output' ))
{
$CI->output->set_output( $this->fetch($template) );
}
else
{
$CI->output->final_output = $this->fetch($template);
}
return;
}
else
{
return $this->fetch($template);
}
}
}
// END Smarty Class
Here are all the files included in the download:
The CodeIgniter library class used to bridge to Smarty:
/system/application/libraries/Smarty.php
Smarty plugin functions to bridge to CodeIgniter classes:
/system/libs/smarty/libs/plugins/function.ci_config.php /system/libs/smarty/libs/plugins/function.ci_db_session.php /system/libs/smarty/libs/plugins/function.ci_form_validation.php /system/libs/smarty/libs/plugins/function.ci_language.php /system/libs/smarty/libs/plugins/function.ci_validation.php
Example code:
/system/application/controllers/example.php /system/application/language/english/label_lang.php /system/application/views/templates/example.tpl /system/application/views/templates/header.tpl /system/application/views/templates/footer.tpl
Step 5) Update CodeIgniter's config
In the /system/application/config directory, there is a file called autoload.php. Edit that file and add 'smarty' to the array of library classes to be autloaded:
$autoload['libraries'] = array(…,'smarty');
Step 6) Run the example
If you installed everything correctly, when you go to http://yourdomain/example you should see a screen like this.
- Share:
- Digg
- Del.icio.us