Smarty as a “Sub-Language”

By Deane Barker

I’ve been spending some time working with Smarty lately. This is ostensibly a “templating language” for PHP. But I think it goes beyond that. I assert that Smarty has become a sub-language all by itself.

First of all, for the record, Smarty is astonishingly well-done. Joe tried to get me to use it for about a year, and I resisted because I’ve hated most templating languages I had worked with. (Lately, Joe is bugging me to try Rails, so I’m sure I’ll do that about a year from now. I’m usually about a year behind Joe.)

I’ve spent just two weeks or so with Smarty, and I’ll never, ever go back. It’s one of those rare things that was written the way you would have written it if you had all the time in the world and were a lot smarter than you actually are.

What I love about Smarty is the extensibility. You can take any logic and wrap it up into a function or a modifier and expose it to Smarty, so it can be used in templates. Anything – if you can write it in PHP, you can reduce and simplify it down to a tag in Smarty.

This means that you could essentially write a new programming language in Smarty – a language that runs within PHP. Smarty already includes variables, flow control, several built-in modifiers and functions, and an include system that’s essentially a way to create user-defined functions.

Once you start wrapping up some advanced functionality into Smarty tags, you could create an entire language, teach your template developers how to use it, and they’d never know they were actually using PHP unless you told them. They’d essentially be “programming” in a sub-language that runs inside of PHP. (If they ever ask you what language you’re teaching them, just string three letters together – “RTI” or “DBN” or something. They’ll buy it.)

Let’s consider ColdFusion, which is the language we would come the closest to if we pushed Smarty as far as it could go. This code in ColdFusion pulls a recordset, loops through it, and prints everything out.

SELECT * FROM news #news.title#

Now, here’s the same thing in a Smarty template:

{query name="news"}
  SELECT * FROM news
{/query}

{foreach from=$news item=article}
  {$article.title}
{/foreach}

All this took was a custom, 10-line block function (written like this) that allows the template author to provide the SQL statement to be executed and returns a two-dimensional array. (Before you send the hate mail, yes I know this is wrong. I know this is a perversion of everything Smarty is supposed to do. I’m just trying to make a point here.)

So Smarty can be made to function very much like ColdFusion. It’s not hard to take this further. Assign the $_GET and $_POST variables, and you can provide some dynamic functionality. This assignment:

$smarty->assign('_get', $_GET);

Will let you do this in the above template:

{query name="news"}
  SELECT * FROM news WHERE title LIKE '%{$_get.q}%'
{/query}

Now template authors can create a mini-app that searches a database table. It’s not hard to see how you could make scripts to let them update tables as well.

But, you may say, Smarty has to be invoked from a PHP page, so the templates cannot be URL-addressable. True, but you can automate this. You can just route all incoming requests to the same PHP page, like this:

AliasMatch ^.*$ /template_loader.php

Then, in that file, do something like this:

$smarty->display($_SERVER['REQUEST_URI']);

This will load whatever template was called in the (fake) URL. So now template authors can start stringing templates together. Before you know it, they’ve gone and built a simple app. By themselves. Without you. In a language that you gave them. That runs inside of – and is essentially controlled by – PHP.

Your programming environment has now been split into a “main” language and a “sub” language, both of which you have control over. You can give your template authors as much or as little functionality as you want (you “wrote” the language, remember). They can solve as many problems as they can with what you’ve given them. For other problems, you can tackle them in “real” PHP and just provide the result, or you can encapsulate the algorithm and expose it to Smarty via a function or modifier.

Is this a good thing? I can’t decide. But it sure is interesting, ain’t it?

This is item #294 in a sequence of 357 items.

You can use your left/right arrow keys to navigate