Smarter PHP with Smarty

Have you ever noticed that some of the features that make PHP so popular and useful are the very same features that come back to bite you as your project evolves and gets larger and larger?

Have you ever noticed that some of the features that make PHP so popular and useful are the very same features that come back to bite you as your project evolves and gets larger and larger?

When you’re building an application prototype in PHP, you tend to do things in a quick fashion. You don’t structure your code particularly well. You create a .php file for each page, and maybe a single, large .inc file for all of your common routines. You opt for functional programming rather than building reusable objects. And, worst of all, you liberally mix PHP and HTML.

It’s quick. It’s easy. And it kills you in the long run.

When your project grows to the point that a non-programmer gets involved in the design and appearance of the application, things get hairy. You end up trying to explain to your designer the importance of editing with tools that don’t mangle PHP code. “It’s safe to change this and that, but don’t touch anything between <?php and ?>.” Ugh.

Instead, what you really need is a simple and powerful templating system — a system that lets you separate code from layout, design, and markup. Templating allows the programmer (you) and the designer to work independently on separate files without worrying about stomping on each other’s work.

This month, we begin diving into one of PHP’s more popular toolkits: the Smarty template engine.

A What?

If you’ve ever heard Rasmus Lerdorf (the creator of PHP) speak about PHP, you might know that he often describes PHP as a templating language. That’s what he originally thought he was building when he started developing PHP.

From his semi-purist point of view, if more than a small percentage of your HTML pages end up being blocks of PHP code with complex logic, you’re doing something wrong. That logic belongs elsewhere — broken out in an underlying library, or even coded as a C extension.

Realistically, though, most people don’t code PHP that way. Most of us think of (and use) PHP primarily as a programming language, not a templating language.

Why Smarty?

As mentioned earlier, Smarty has become quite popular. Smarty blends power and flexibility in a way that doesn’t compromise performance. It sports a number of features that other web-based templating systems don’t.

In Smarty, the delimiters are customizable. You can use {}, <!– {} –>, or whatever works best for your designers’ template editing software (such as FrontPage, HomeSite, Dreamweaver, or vim). Also, the Smarty language is quite familiar. As you’d expect, it’s very PHP-like. In fact, you can use arbitrary PHP in your templates. It goes against the notion of separating design from code, but you can do it.

Most importantly, though, Smarty is fast. The speed comes from a very smart design decision: use the PHP interpreter for all the hard work.

Rather than evaluating a page template upon each HTTP request, Smarty processes templates only when they change. It then saves (or caches) the result as PHP code. That means Smarty templates take full advantage of PHP opcode caches and accelerators (see “PHP Caching and Optimization” in the April 2003 “LAMP Post,” available online http://www.linux-mag.com/2003-04/lamp_01.html).

Said another way, Smarty is a templating system written in PHP that generates new PHP code that the PHP interpreter can then run at full speed.

Installation

Okay, enough bragging about how cool Smarty is. Let’s get down to the business of installing it. Head over to the Smarty download page (http://smarty.php.net/download.php) and fetch the latest version. Unpack the tarball and move the contents of the libs subdirectory into a location in PHP’s include_path.


$ tar -zxvf Smarty-2.5.0.tar.gz
$ mv Smarty-2.5.0/libs/* /some/web/dir

To verify that the Smarty files are installed in a good location, create a simple test.php script to load Smarty and create a Smarty template object.


require(‘Smarty.class.php’);
$smarty = new Smarty;

If that script executes without error, you’re all set. Installation is that easy.

If you happen to look at the files moved (from the original libs directory), you’ll notice only a few PHP files. But there’s also a plugins subdirectory with a ton of little add-ins available. We’ll come back to those plug-ins next month — plug-ins are used to extend Smarty.

A First Project

The best way to get started with Smarty is to simply jump in and start a new project. Every Smarty project requires a few subdirectories: templates, configs, cache, and templates_c.

You can customize the names of these directories, but it’s probably easiest to use the defaults. Furthermore, there’s no need to place any of these directories under your web server’s document root. Instead, put them where only you and the designers can get at them. There’s no reason to show off your templates to the rest of the world.

The files you create will be placed in the templates and configs directories. Smarty and PHP need write access to the template_c and cache directories, so some permission changes are in order. Make sure that the web server user (often nobody, www-data, or something similar) can read and write those two directories, and restrict access from most others.


$ sudo chown nobody template_c cache
$ sudo chmod 700 template_c cache

Those commands ensure that the web server and only the web server can make changes there.

With all that in place, let’s create a simple template and the PHP file that will be used to instantiate and process the template.

First, the template. In the templates directory, create a file called index.tpl.


{* This is a Smarty comment *}
This is a test of Smarty. My favorite
operating system is {$os_name}!

Notice that the comments are delimited by {* and *}, and the $os_name variable is also surrounded by {}, Smarty’s default delimiter. To drive the template, create an index.php file that looks like this:


// smarty template test script
require(‘Smarty.class.php’);
$smarty = new Smarty;
$smarty->assign(‘os_name’,'Linux’);
$smarty->display(‘index.tpl’);

As you can see, it doesn’t take much code. You simply load the Smarty class, create an instance of it, populate any variables, and then ask Smarty to evaluate, build, and display the template. Request index.php in your browser. You should see it display:


This is a test of Smarty. My favorite operating system is Linux.

If so, congratulations! You’ve created your very first Smarty-based application.

Syntax and Control

Now that the basics are working, you need to know about Smarty’s basic syntax and control structures.

To embed simple PHP code in your templates, you can usually just surround the code with {…} delimiters and a slightly funky syntax:


{if $color eq “green”}
Hey, Kermit.
{else}
What’s up, Piggy?
{/if}

Function calls are a little odd. The have an XML “attribute=value” style feel to them. One benefit of this syntax is that the order of values passed to functions is not set in stone.


{save_stuff directory=”/tmp”}

Functions are either built into Smarty, such as the basic control structures, or they’re defined in Smarty plug-ins.

Complex data structures are easy to access in Smarty, too. Imagine that index.php assigns an associative array to a variable. You can access the values in your template using dot notation or using positional notation:


Height: {$image.height}
Width: {$image.width}
Name: {$image[0]}

And so on and so forth. Object attributes use the natural syntax {$image->name}. There is also a reserved variable named $smarty that you use to access a host of other functionality, notably the contents of PHP’s super-globals:


Smarty running on:
{$smarty.server.SERVER_NAME}
at {$smarty.now|date_format:”%Y-%m-%d”}

Stay Tuned

Next month we’ll look at some of Smarty’s other functions, features, and plug-ins.



Jeremy Zawodny plays with MySQL by day, and spends his spare time flying gliders in California and writing a MySQL book for O’Reilly & Associates. Reach him at Jeremy@Zawodny.com

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62