First released in January 2001, Smarty has become a stagnant, bug-ridden mess—and also the most popular PHP templating engine in use today. But it shouldn't be. No Smarty was created to warn developers about its use and encourage the use of superior alternatives.
Is Smarty right for me?
[08-Aug-2008] No. Despite its name, Smarty is not the most intelligent solution available to you.
It’s true that Smarty has received numerous testimonials over the years. However, it’s clear that most of these testimonials are from developers who are unfamiliar with multitier architectures. For these users, the concept of separating business logic and presentation is (understandably) an innovative concept. But Smarty is only one such way of achieving this separation, and no longer the best alternative available (if it ever was).
Smarty has a list of benefits on its website. Let’s go through some of them and shoot them down.
Caching
Here’s what Smarty says:
Smarty provides fine-grained caching features for caching all or parts of a rendered web page, or leaving parts uncached. Programmers can register template functions as cacheable or non-cachable, group cached pages into logical units for easier management, etc.
OK, so let’s take a look at Smarty’s caching system. To enable caching, you would write
This sets up caching with the default lifetime of 3600 seconds (that’s one hour). What if you want to use an alternate TTL–say, 30 minutes? Then you would write
Oh, of course, $smary->caching = 2;. What else would it be? Well, a constant instead of a magic number would be nice. But wait, why does the TTL even depend on a magic number being set for caching? If caching is going to be accessed directly through a public property of Smarty, shouldn’t it at least be a simple Boolean, either true or false?
There are a number of headaches like these baked into Smarty. Far from mere aesthetic concerns, this unintuitive design has a real effect on day-to-day usage when you are forced to refer to the documentation again and again for even the most common uses.
Syntax isn’t the only issue. Caching with Smarty can be a challenge when serving a load-balanced Smarty-based application from multiple servers. The cache file generated by one server cannot be reused by another unless a clustered file system like GFS or OCFS is used.
Let’s take a look at configuration.
Configuration
Smarty can assign variables pulled from configuration files. Template designers can maintain values common to several templates in one location without intervention from the programmer, and config variables can easily be shared between the programming and presentation portions of the application.
Smarty allows you to store files in INI format and then load them. There’s a PHP function for this already. It’s called parse_ini_file(). Even if you’re resistant to using PHP in view templates, configuration loading should happen in the business logic, anyway. (Incidentally, Smarty doesn’t use this function, instead opting for its own parsing mechanism for no discernible reason.)
Security
Templates do not contain PHP code. Therefore, a template designer is not unleashed with the full power of PHP, but only the subset of functionality made available to them from the programmer (application code.)
Never think that an application is more secure simply because the template engine claims that it makes it more secure. Any security gain you might see from turning off the {php} tag in Smarty is offset by the dramatically increased inflexibility for the template developers. Believe it or not, out of the box Smarty does not even allow a template developer to format a number. The end result is that the back-end developers end up taking on a lot of the responsibility of the front-end developers, usually by creating plugins for such inane tasks as converting to an integer. While there’s no data on this, it’s likely that most websites using Smarty have the {php} tag enabled–in which case, what’s the point of Smarty in the first place?
In any event, the most common security hole for websites today is not a result of front-end developers at all, but lazy developers who let unfiltered input modify data directly–something that no template engine can possibly defend against. For real security, hire security-minded developers instead.
Easy to Use and Maintain
Smarty has this to say about its ease of use:
Web page designers are not dealing with PHP code syntax, but instead an easy-to-use templating syntax not much different than plain HTML. The templates are a very close representation of the final output, dramatically shortening the design cycle.
In our experience, Smarty dramatically increases front-end development time–even with the {php} tag enabled–because of its numerous unintuitive behaviors!
But let’s look at some examples of Smarty’s syntax. In the end,
is not significantly simpler to use or maintain than
And Smarty is demonstrably not easy to maintain when
prints “foo”, tipping you off to the fact that you meant to print a variable but forgot the dollar sign, and
prints nothing.
When assigning variables, this
is certainly less readable than this
Of course, these are basic examples. The real test of a syntax, be it Smarty or PHP, is how it handles more complex tasks. In that light, this:
is initially impenetrable to new users, compared to something like this, which you might see in an MVC application:
(The most obvious solution, {assign var="foo" value={my_helper var1="bar" var2="qux"}}, is invalid, of course.)
Variable Modifiers
The content of assigned variables can easily be adjusted at display-time with modifiers, such as displaying in all upper-case, html-escaped, formatting dates, truncating text blocks, adding spaces between characters, etc. Again, this is accomplished with no intervention from the programmer.
As mentioned above, the idea that this is accomplished with “no intervention from the programmer” is optimistic at best. Smarty comes with 22 of these modifiers, but “the programmer” will have to add a number of new ones in order for the front-end developer to do his job. New requirements will continue to come up, again and again, and eventually the benefit of leaving the {php} tag disabled will be called into question, resulting in it being enabled.
Template Functions, Filters, Plugins, and Add-ons
Many functions are available to the template designer to handle tasks such as generating HTML code segments (dropdowns, tables, pop-ups, etc.), displaying content from other templates in-line, looping over arrays of content, formatting text for e-mail output, cycling though colors, etc.
The programmer has complete control of template output and compiled template content with pre-filters, post-filters and output-filters.
Almost every aspect of Smarty is controlled through the use of plugins. They are generally as easy as dropping them into the plugin directory and then mentioning them in the template or using them in the application code. Many user-community contributions are also available. (See the plugins section of the forum and wiki.)
Many user-community contributed Add-ons are available such as Pagination, Form Validation, Drop Down Menus, Calander Date Pickers, etc. These tools help speed up the development cycle, there is no need to re-invent the wheel or debug code that is already stable and ready for deployment. (see the Add-ons section of the forum and wiki.)
Smarty has many names for view helpers. View helpers are useful, but there are better templating solutions available that support view helpers and have a wider range of features. The truth is Smarty’s default list of variable modifiers do little to speed front-end development, and many add-ons contain code that has no place in the template engine. This is the result of improper separation of concerns.
Resources
Templates can be pulled from any number of sources by creating new resource handlers, then using them in the templates.
“Resources” (really, storage adapters) allow you to serve templates from sources other than a file system. Smarty cites examples including databases, socket connections, shared memory (e.g., memcache), and even LDAP. LDAP?
Caching your templates in memory is smart, but templates should always be kept on a local file system if at all possible. Load them from the file system, then cache to memory.
It’s commendable that Monte Ohrt, the developer of the feature, tried to generalize what was clearly a request from the community for the ability to serve templates from a database. But PHP has supported streams since 2002 with the release of PHP 4.3. Even though rewriting this feature to use streams would allow it to work seamlessly with existing stream code users may have written for this purpose, not to mention giving every Smarty-based application using resources a large performance boost, there has been no movement on this for six years.
Debugging
Smarty says this about its debugging capabilities:
Smarty comes with a built-in debugging console so the template designer can see all of the assigned variables and the programmer can investigate template rendering speeds.
Far from a nice interface a la Firebug, this is an unreadable 200-line data dump.
Compiling
Smarty compiles templates into PHP code behind the scenes, eliminating run-time parsing of templates.
Smarty compiles down to PHP. This should give you a hint. Really.
Performance
Smarty performs extremely well, despite its vast feature set. Most of Smarty’s capabilities lie in plugins that are loaded on-demand. Smarty comes with numerous presentation tools, minimizing your application code and resulting in quicker, less error-prone application development/deployment. Smarty templates get compiled to PHP files internally (once), eliminating costly template file scans and leveraging the speed of PHP op-code accelerators.
Nothing in PHP is going to be faster than PHP itself with a proper byte code cache like APC.
…
So if Smarty isn’t the right tool for the job, what is? There are alternatives that do everything Smarty does, only better. Our favorite PHP framework at the moment is Zend Framework. It supports caching, configuration, filtering, view helpers, and more. It’s also thoroughly documented, object-oriented, and unit tested. There are other alternatives, as well. Symfony, for example, might be more your speed. Or PHPTAL.
But please–no Smarty.