Between roughly 2005 and 2015, a lot of PHP applications were built around Smarty. Templates lived in .tpl files, PHP handled the logic, and the two were meant to stay apart. Plenty of those applications are still running real businesses, and plenty are stuck: the Smarty copy inside is a version from the PHP 5 era, it won't run on a current PHP, and nobody wants to be the person who touches the templates.
You don't need to throw the application away to fix this. Here's how we'd approach a Smarty system, in the order that keeps risk lowest.
Find out what you're dealing with
Before choosing a plan, answer these questions about the codebase:
- Which Smarty version is it? You can read the version in
Smarty.class.php. Smarty 2, 3, 4 and 5 are different enough that the answer changes everything. - How is it loaded? A copy committed into the repository, or installed with Composer? Has anyone edited the copy?
- Are there custom plugins? Look in the plugins directory for files named like
function.something.phpandmodifier.something.php. Count them. - Is there PHP inside the templates? Old templates sometimes run PHP blocks, which later Smarty versions disabled and then removed.
- How many templates are there, and how many are actually in use?
- What calls Smarty? The application may use the old Smarty 2 method names, such as
assign_by_ref,register_functionandclear_cache, throughout its controllers.
Why old Smarty is a problem
Smarty 2 was written for PHP 5, and it hasn't been maintained for a long time. It'll throw errors or warnings on modern PHP, and any security fixes in later releases don't reach you. Smarty 3 and later are maintained, and Smarty 5 is current, so the target exists. The practical question is how to get there.
Upgrade Smarty first, before you change anything else
The cheapest big win is usually just getting a supported Smarty. It lets you move the PHP version up too, since the two are tied together, and it doesn't require changing a single template design.
Go through the major versions and read the upgrade notes for each, since the breaking changes are documented. A few things to expect:
- Smarty 3 renamed the methods from snake case to camel case. A compatibility class,
SmartyBC, keeps the old names working so you can migrate calls gradually instead of all at once. - Compiled templates are version-specific. After any upgrade, empty the compile directory (often called
templates_c) and make sure the web server user can still write to it. A surprising number of "the upgrade broke the site" reports are this. - Smarty 5 moved to namespaces, so class references change.
- Custom plugins need testing individually. Their signatures usually survive, but the PHP inside them often runs into the PHP 8 changes we describe in the PHP upgrade guide.
Compile every template before users do
Smarty compiles a template the first time it's rendered. That means a syntax problem in a rarely visited page stays hidden until a real person hits it. Compile everything in bulk on staging instead. Smarty 3 and 4 include a compileAllTemplates() utility for this (check your version's documentation for the current equivalent), or you can write a short script that loops over every .tpl file and calls fetch() with dummy data. Either way, you find the broken template in a test run, and not in a support ticket.
Turn on output escaping
This is the single most useful security change in a Smarty system. Old templates frequently print values without escaping them, which is a cross-site scripting hole waiting for a bad value. Smarty can escape everything by default:
$smarty->escape_html = true;
In newer versions this is set through a method rather than a property, so check the documentation for yours. The catch is that anywhere the application deliberately outputs HTML (a rich-text article body, say) will now show raw tags on the page. Mark those places as trusted:
{$article.body nofilter}
Turn it on in staging, click through the main pages, and fix what looks wrong. The pages that need nofilter are a short list, and the list itself is useful, since it shows exactly where your application emits raw HTML.
Deal with logic that crept into the templates
Smarty lets a template call PHP functions as modifiers and run non-trivial conditions. Over the years, old systems accumulate business rules in .tpl files: price calculations, permission checks, even database lookups through custom plugins. This makes the templates hard to test and hard to move.
You don't have to fix it all at once. Whenever you're in a template for another reason, move the logic into the PHP that prepares the data, and leave the template to display it. Over time the templates get dumber, which is what you want.
Staying on Smarty is a legitimate answer
A common assumption is that Smarty has to go. It doesn't. It's maintained, and a current Smarty on a current PHP version is a sound place to be. If the application is otherwise healthy, upgrading Smarty and tidying the templates may be all you need.
Moving to another template engine, such as Twig or Blade, makes sense when you're also moving the application to a framework that uses one. If you do go that way, do it route by route, with old and new running together, instead of converting every template up front. Syntax conversion helps with simple templates, but it isn't mechanical: filters, plugins and logic all need judgment. We describe how to run both systems at once in running old and new PHP side by side.
Check pages, not just code
Template changes are visual, so test them that way. For each key page, render it with fixed test data before and after the change and compare the HTML. Strip out the parts that change on every request (CSRF tokens, timestamps) and the diffs become readable. It's the same idea we describe in adding tests to legacy PHP code.
Common questions
Can I use Smarty 2 on PHP 8?
Not reliably. It was written for PHP 5 and will throw errors on modern versions. Upgrade Smarty as part of the PHP upgrade.
Will upgrading Smarty change how my pages look?
It shouldn't, if the templates are only displaying data. The places that change are the ones that relied on removed features, or that now get escaped when they didn't before. That's why we test pages before and after.
Do I need to convert to Twig or Blade?
Only if you have a reason beyond Smarty's age. A maintained Smarty is fine.
What if nobody has the original source or documentation?
That's more common than you'd think. Start with the inventory above, then read documenting an undocumented codebase.
Running a Smarty-based system you can't upgrade?
We work on these regularly. We'll tell you what's blocking the upgrade, and what it takes to get you onto something supported.
See our legacy system support