Smarter Parsing with Smarty

Annika Backstrom
in misc, on 10 August 2008. It is tagged #Web, #PHP, #Programming, and #smarty.

My day job makes heavy use of Smarty for page templating. We're currently moving away from XTemplate, which I generally don't like, but it does have one nice feature: curly braces in CSS and JavaScript blocks aren't interpreted as template tags. I set out to determine if this behavior could be easily applied to Smarty.

The Problem

By default, Smarty uses curly braces to denote template tags, ie. {foreach from=$widgets item=widget}. The left and right tag delimiter are configurable, defaulting to { and }, respectively. Whitespace is allowed after the left delimiter. This means the following CSS rule is interpreted as a Smarty tag:

<style type="text/css">body { font-size: 80%; }</script>

This would generate an error, claiming "syntax error: unrecognized tag: font-size: 80%." You can use the {literal} tag to escape a block of text, or use {ldelim} instead of "{", or change the delimiter to something less common like <!--{. I would prefer the XTemplate behavior.

The Solution

Here is a patch that modifies Smarty to ignore left delimiters which are immediately followed by whitespace. {foreach} would be parsed, but { foreach} would not. This has potential security implications since an errant space could expose part of your template to the world, but it has the potential to simplify some very convoluted markup.

I've done some limited testing (including creating a one-character template tag) and it seems to work fine. I'll have to try with some more complicated templates, but hopefully this will make its way into our Smarty as a custom mod. (Thankfully we deploy Smarty via Subversion, so it's relatively easy to mod the local library install.)