When we (as in my business partner and I) started developing the third version of our open source program (our first ever ‘commercial’ product), Olate Download, we had to decide how we were going to handle templates to allow the user to customise their site. At the time, the options available to us were to use Smarty (or find a different engine) or create our own template engine to handle it. We had a look at Smarty and decided it was too complex for our simple download management application. As such, we went ahead and created our own system.
Looking back at our engine now, it does its job, but it is limited. We added our own very basic control structure syntax and built in includes and even a simple language system. It did the job well.
Several months after we released that product, I started development on our latest product – a paid application to manage software sales. This too was to have a template system because it is easiest way to allow customisation of the product. I had recently read an article in PHP Magazine about an engine called Savant2. After playing around, I decided that this time, I didn’t want to create my own system, but I would use Savant to power the template system.
Side note: One of good things about using a 3rd party system rather than writing your own is that the developers of the product are usually dedicated to improving that product. They are not involved in your development so they work on their program, improving, bug fixing and updating. This means that part of your product improves without you needing to do much, except update your integration of it! You can work on other parts of your product whilst that bit is handled by someone else.
Comparing Savant to Smarty is difficult. Yes they are both template engines, but Savant does not compile its templates. Nor does it have its own built in scripting syntax. It uses PHP. Many people also consider Smarty to be ‘heavy’ with lots of complex features that aren’t necessarily needed in all situations. For example I didn’t need caching or compiling in my products and I also wanted to work with PHP syntax in the templates, not the custom syntax that Smarty has.
[quote=”Savant Website”]In short, PHP is itself a template language, so in general there is no need for another template language on top of it. However, there are some specific cases where using customized markup is safer than PHP; for that reason, Savant allows you to hook in a custom compiler for your own purposes.[/quote]
The idea behind Savant is (what any PHP developer should be trying to do) to separate design from the application itself. i.e. separate the HTML from the PHP code that performs the majority of the functions. This is Smarty does 100% – you see no PHP in the templates. But in Savant, this is not the case. Whilst all the main code is in separate PHP files, there is some PHP in templates.
Savant always has 2 files. One of them is the PHP file which does most of the work and then other is a template file (usually with the .tpl.php extension).
To illustrate this, here is an example, where I have Savant2.php in the same directory:
$template = new Savant2(); // New Savant2 object
$title = 'Customers';
$list = array(array('name' => 'James', 'Country' => 'UK'), array('name' => 'Jill', 'Country' => 'Canada'));
$template->assign('title', $title); // Assigning a var to be used in the template
$template->display('customers.tpl.php'); // Display the template now
In the HTML template customers.tpl.php, I would have this:
... HTML ...
customers as $key => $value): ?>
There are no customers.
... HTML ...
This would echo the 2 customers I added to the $list array. Notice how the variables assigned from the $template->assign() call are class variables using $this->varname. Also notice that I’m using PHP control structures (the shortened versions) within the template.
That is a very simple example and the real usefulness of Savant comes with its various plugins and filters.
[quote=”Savant Website”]Template plugins are objects you can call from your template to automate repetitive tasks. Savant loads plugin objects dynamically as you call them, so you don’t have to pre-load them. However, if you want to pre-load a plugin, you can sometimes configure its behavior in advance; whether or not a plugin can be configured depends on the specific plugin.[/quote]
The plugins available include form generation, image/CSS/JS display, and general options like date formatting. Of these, one of the most useful is the option list plugin.
One of the problems with dynamically generated option lists is selecting the default value. This is made easy with the options plugin.
For example, when editing a database record, I could have this code:
// Status list menu options
$status_options = array(1 => 'Active', 0 => 'Disabled');
This sets the status drop menu options and assigns them to the template variable. Elsewhere in the code, I have already obtained the data from the record in the database.
In the template, I can then create the list, populate it with the 2 options and also set a default value based on the data returned from my database record:
plugin('options', $this->status_options, $this->user['status']); ?>
Here, the plugin method is called. The first parameter is the name of the plugin, the second is the array of options and the third is the default value. This value could be at any point in the list, it only needs to reference the array key of the options you provide. The output might look like:
Another really useful plugin is the HTML checkbox. I’m sure everyone has encountered the problem of trying to determine the value of a ticked checkbox! Savant makes it easy with the checkbox plugin so it is easy to set a value when ticked. You can also just as easily have it set as a value when you’re editing a database record (for example) like with the option menu above.
Savant2 works with both PHP4 and PHP5 (Savant3 is written specifically for PHP5).
From working with Savant since around October last year, I have been able to do everything I want to do with it. I found that it has easily coped with a large application such as my own, and I expect it could easily scale both ways. It is not bloated, it is well coded (includes PHPDoc source documentation) and it does exactly what I need it to do.
There are plenty of engines around. It is all about finding one you like and that suits your project. You’ll find a useful list of engines at http://www.sitepoint.com/forums/showthread.php?threadid=123769
This will be my last post for just over a week. I’m going on holiday to Canada tomorrow and will be back next week on 5th when I shall resume my regular (every other day) posts.