Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

 

Revamped Template Parser for SilverStripe 3

SilverStripe has always had a pretty elegant template language (the language used to describe how...

Comments 11

by Hamish Friedlander

Posted 12 October 2011

Read post

SilverStripe has always had a pretty elegant template language (the language used to describe how data from the application should be inserted into a document - be that of a web page or anything else). It was simple to learn and kept the designer insulated from complicated back-end code.

Unfortunately the implementation of that language in earlier versions of SilverStripe lacked the same elegance. The code was a mess of regular expressions, which made it hard to read and even harder to extend. It had arbitrary limits on what parts of the language could be used where, it was impossible to extend except by editing the core files, and it had hooks into many other parts of the framework; breaking encapsulation and distributing responsibility in non-obvious ways.

There were good reasons for most of this, but the core reason for much of it was the lack of a good parser generator for PHP.

For the non-technical, a parser is a program that takes something in a particular language (in this case, the SilverStripe template language), and understands it - breaks it down into a structure a computer program can understand based on the rules of that language.

Although you can hand-write parsers you probably shouldn’t, especially for complicated document structures. They become hard to read and maintain - the exact problems we already had. Instead you use a parser generator. You describe how the language you want to parse looks and the parser generator creates the parser for that language automatically.

If this all sounds quite complicated, it is. The way you describe how a language looks for a parser generator is extremely technical. The parser generators themselves are complicated pieces of software. And, at least at the time we were looking, there weren’t any for PHP that were maintained and had a stable release, which would mean we’d have to write one ourselves. All of which explains why when the original SilverStripe template language was written, we didn’t use a parser, bypassing the issue entirely by using another method.

This changed when we started to work on SilverStripe 3. The initial core team sat down and built a list of what things we’d like to change in SilverStripe if we could, and top of the list was the template language. 

In the mean time, I’d been experimenting with a new type of parser generator, called PEG. Unlike traditional parser generators, this new type used concepts more familiar to software developers. It was also much easier to implement - so much easier that I had already gone from proof of concept to an almost complete solution during a previous project. As a result, pretty much the first task we did during SilverStripe 3 development was to prototype a SilverStripe template language parser using this new tool. While we were at it, we improved the language - made it more orthogonal (if something works, it should work the same in every situation), consistent, extensible, readable. We added support for “Up”, which gives the parent context - a long asked for feature.

The result is a much superior template language implementation. Although for basic usage there is no apparent change, under the hood is a complete swap. Advanced users will find much to like.

The ultimate validation for me came about three weeks later. There was an additional feature we wanted to add to the language (an improved syntax for internationalised text). Another SilverStripe developer Julian Seidenberg was able to add this feature with almost no help despite having no previous experience writing parsers, and without introducing any side effects - something that would have been considered so difficult that it would not have been attempted in the old engine. 

Now that the parser generator is in the SilverStripe Framework, there are many other opportunities to replace hand written parsers in the system, and it offers many possibilities for website developers too. Just some of the potentials: a fully standard compliant email address parser; a bbcode parser; improved introspection. 

If you’d like to check out the parser generator, it’s available on my personal github at https://github.com/hafriedlander/php-peg. Or you can see it in use in SilverStripe master - the main repository is at https://github.com/silverstripe/sapphire and the template parser itself can be viewed at https://github.com/silverstripe/sapphire/blob/master/view/SSTemplateParser.php.inc