Is PHP on it's own a good enough templating language, or should one use something like Smarty to write PHP templates in?
The good thing with using a specialized templating language is that it forces you to reduce the amount of logic in the templates, hopefully leading to a template without any controller logic. Whereas if you use the same language, the temptation to, say, "only check if the user is logged on" in the template grows.
Just look at most JSP templates (or template-less PHP code, for that matter).
It depends who is to edit the templates.
If only a mall number of trusted people are to edit templates, then using PHP as its own templating language is lightweight, quick and requires no new syntax knowledge.
On the flip side, one typo can break your app very easily.
Smarty is great for separating code from look in a formalised way. It is not generally possible for a template error to break the site in the same way as it would in PHP.
On the flip side, the learning curve is greater for people who haven't used Smarty's markup before, and it requires some heavy caching in order to perform at a reasonable pace.
I'd suggest using a templating engine, though I'm not very fond of Smarty, mainly because too much is possible with it, thus a lot of controller logic can be embedded in the template (which is a bad thing, obviously).
It might be tempting to say, for example, that you are the only one writing the code and no one else will muck about it, however, soon enough you might become time-constrained and trying to do things as quick as possible and not necessarily the right way and that might return later to bite you.
Don't forget that PHP's original purpose was to be a templating language. I work by the "conditionals and loops" principle: in general, I only use PHP's conditionals and loops in my templates, and only for generating HTML code. Any data massaging, business logic etc. is elsewhere (like a model or controller). It IS possible to be disciplined with PHP templating.
Alex P has a good point, though. If you don't trust the other folks who may be working on this code, you may have to force them to use something like Smarty.
It depends on what your tastes and requirements for a template language are. PHP is of course a template language in itself, and using it for this purpose will bring you more efficiency in execution resources, less code complexity and easier handling. Keep in mind that PHP isn't Java, most of the time there is no need for bloating stuff up needlessly just to gain another bullet point on the shrinkwrap for your costly CMS or something similar.
There are, however, some clear indications where a separate template language might be called for, depending on your judgement of course:
Code security: Once you allow users to edit PHP inside your application, you are handing them the keys to your webserver. Granularity of code execution is very hard to achieve in PHP, it just isn't designed for it. This means, the editor of a "template" automatically has access to the whole PHP environment, including the internals of your software. Though some methods of restricting access exist, sometimes it is just easier to use a template language that doesn't provide any critical features to begin with.
Sloppyness prevention: For most projects, it makes sense to keep business and presentation logic separate. Even better, you can opt for a model-view-controller paradigm, which is all the rage nowadays. However, there is always the temptation of putting "business" code inside your templates. Having a template language prevents this.
Validation: The success of executing a PHP template without runtime or compiletime errors often depends on the exact state and context of the environment. This means, in most projects it becomes difficult to judge programmatically whether a given "template" will execute without throwing errors. The limited facilities of a template language can enable you to validate the integrity of a template beforehand, pushing possible errors into the model or controller logic, where they might be easier to identify and debug.
There are many more reasons for and against using template languages, all of them are certainly valid in different contexts. Also, the choice of the language itself is important for the task you want to accomplish. Personally, I'd opt against the use of a separate templating engine except for very special circumstances, but as always there is no substitute for your own judgement. ;-)
You need to consider whether the benefits of introducing Smarty justify the learning time and slight performance overhead over raw PHP:
- If your pages are being coded by non-PHP developers then perhaps avoiding PHP syntax would be beneficial
- You could argue that Smarty improves readability
however, since PHP is itself a templating language you don't actually need anything else.
If you don't like embedding <?php echo $value ?>
tags in your HTML you can use heredocs. For example:
<html> <?php $title = "Example Page"; $content = "Some content here"; echo <<<DYNAMIC_CONTENT <head> <title>$title</title> </head> <body> $content </body> DYNAMIC_CONTENT; ?> </html>
Don't bother if you're going to make a 5-10 page website for somebody who'll never upgrade or redesign the thing. Do it by any means if you think you'll probably be called to mess with it again couple years later. You'll be glad you did. Take whichever templating system where you like the documentation. Don't worry about another syntax to be learned: chanches are you already had to learn regexes, SQL, (X)HTML, CSS, Javascript, maybe JSON or XSLT - it's just one more and won't take long.
Disclosure: I'm a long time and happy Smarty user. Extremely happy when somebody asks for 'just a small change on that web you made back then'. I first heard about the difficulty of learnig Smarty couple years after starting using it almost without noticing...
I dislike using a template language on top of PHP, because as has been noted, PHP originally was designed as a template language, and works very well for that. I once heard Rasmus Lerdorf (the guy that originally wrote PHP) give a talk and say something along the lines of "Eventually, someone will use write a simple template language using Smarty" (joking at how complex Smarty has become).
There are situations like Udo stated that call for using a separate template language. Internally however, as long as you have a bit of coding guidelines (like not putting business/database logic in the presentation layer (template), you're okay.
A nice easy way to keep code separated:
function showTemplate($filename, $variables) {
extract($variables);
include('templates/'.$filename);
}
You can get fancy with this, and use output buffering and such to make it return values. But effectively, this gives you a separate namespace to run each template in. If they set variables, it doesn't trample any of your other code (as long as they don't use "global" -- this should be part of the guidelines).
Using this is pretty easy. In your calling (business) code:
$vales = array(
'title' => 'My Site',
'username' => $currentUserName,
'version' => MY_SITE_VERSION,
);
showTemplate('main.php',$values);
In the template:
Hello, <?= htmlspecialchars($username) ?>, welcome to <?= htmlspecialchars($site)!
Effectively, you end up with what Smarty gets you, except the syntax is slightly different (<?= ?> instead of {{ }} or whatever they use), you don't have to learn a new language, and it runs at native PHP speed (instead of interpreted-language-running-inside-an-interpreted-language speed).
Not good enough
PHP makes it easy to output invalid tagsoup, but hard to ensure that (X)HTML is valid and well-formed.
You have to remember to add htmlspecialchars()
every time you output data in HTML. If you forget it, the site will appear to work fine 99% of the time, but may be vulnerable to XSS and CSRF attacks (not to mention that it will be ill-formed).
There are plenty of common constructs that are easy to get wrong – curly braces of if
s get lost in the crowd of tags. When you optionally wrap something in an element you have to repeat condition for opening and closing tag.
PHP tags inside HTML tags look awful.
My favourite solution to this mess is PHPTAL. It's aware aware of X(HT)ML syntax and checks it for you. It also automatically adds entities everywhere – you don't have to remember about this all the time (like in PHP or Smarty).