Smarty as a “Sub-Language”

By on March 21, 2005

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.

(Update: I thought of a much better name for this: “sand-boxed PHP.” That’s what Smarty is — a sandbox into which you can release as much or as little PHP functionality as you want.)

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 modifer.

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

###

What Links Here

Comments

  1. Ominobufo says:

    Yes, I know it could be a dangerous comment but why not trying savant?

    http://www.phpsavant.com/yawiki/

    It's been a while I'm using it and I love the simplicity and the power of that tool. I prefer it over other templating systems because the templating language is php itself, no need to learn another language. Recentely, in need of a sub-set of php directives, for letting external pepole participate in a project, savant let you write your own language parser with a stripped down set of php functions, or, if you prefer, you can write your oun templating language.

    Personally I agree with templatebusiness separation, but this does not mean separating html from php. Reinventing a new templating language (because, php IS a templating language itself) only because graphic designers don't want to learn a little php is not a good reason for reinventing the wheel. And, by the way, you should try mixing up some code generation (http://www.codegeneration.net/tiki-read_article.php?articleId=19) with a templating engine. Interesting thing could arise from that.

    My confused 0.02 euros.

  2. Mike says:

    Wow, perfect timing Deane. I've been poking around a bit half-assed looking for a nice PHP templating engine for a few projects I working on at the office, and Smarty fits the bill perfectly.

    Thanks for pointing me in the right direction helping me to not use my "full ass" while searching for this.

    (Time to start reading the manual...)

  3. anon says:

    Something like

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

    Can be easily substituted with a custom function:

    {get_news_articles assign="news"}

    Now it is template-designer friendly and still accomplishes the task.

  4. Deane says:

    Agreed, I was just trying to show how Smarty can be used to replicate some ColdFusion functionality, and thus become a "sub-language" all its own.

  5. Anonymous says:

    There is a PHP equivalent to Rails, Cake .

  6. we dont need this says:

    while interesting, what advantage does this provide over including scripts? i just see additional overhead in learning a new "sub" language.

    imagine 100 implementations of smarty using 100 "sub" languages. ugh!

  7. Олег Бутузов says:
    $smarty->assign('_get', $_GET);

    WHY?

    what do you know about {$smarty} reserved variable ?

    and actualy Smarty is template engine ? whish means dividing a programming and coding..... in this case it just makes you scripts slower...........

  8. - says:

    very crazy all that stuff, it's very difficult to devide content from business logic and smarty isn't able to do that, i think all template engines or frameworks with the intent to be a template engine weren't able to do this. if you're planing a bigger project than a website, smarty is useless, theories of Business and service objects are much better than any template engine

  9. Den says:

    I think you totally misunderstanded using smarty (or another template system). You give a wrong example why not using smarty. This is true, this way it is dangerous and unusable. I aggre with you.

    You have wanted using smarty like php. It is only a display layer. You would have found useful examples in smarty documentation... IMHO.

  10. Anonymous says:
    I think you totally misunderstanded using smarty

    I misunderstood nothing. I'm quite familiar with the separation of code and presentation. In fact, I specifically noted in the text:

    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.

    I was just trying to demonstrate that Smarty can be used as a sandboxed programming language if you want to -- but just because you can doesn't mean you should. Your own policies are up to you.

  11. Deane says:
    what do you know about {$smarty} reserved variable ?

    Sure enough -- this stuff is assigned automatically. I've never looked at that variable much.

    and actualy Smarty is template engine...whish means dividing a programming and coding... in this case it just makes you scripts slower...

    [sigh] People, this was just an exercise. I have never done this. The fact that I was needlessly trying to assign the $_GET variable proves I have never attempted to apply this theory.

    Are people just reading every third word or something? Why is everyone missing this text:

    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.
  12. fudnik says:

    With all this Smarty talk, here are some things to consider:

    Smarty for Dummies?

    Smarty is not a replacement for good coding!

  13. Mich says:

    Nice, I was moving from ColdFusion to PHP but I was shocked how much more work writing down PHP code is. I say it takes 4 times more effort than ColdFusion "code".

    But I guess for me salvation is here: Smarty! This looks really good!

Add a Comment