Smarter Parsing with 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.)