PHPTI (PHP Template Inheritance) was a fun project to work on, but it’s easy to see, by looking at the commit log, that I stopped maintaining it a while ago. In this blog post, I want to officially announce PHPTI as “no longer maintained” and also reflect on its successes and failures.
First off, I still strongly believe in the concept of template inheritance and feel it is a powerful ally while coding reusable HTML layouts. It makes everything so elegant. A sub-template defines which template it wants to inherit from, and no controllers or other layers need to intervene.
I was first introduces to template inheritance by Django’s templating engine. With PHPTI, I wanted to make a similarly elegant implementation, only in PHP code, where PHP was the template engine itself. I think I succeeded in coming up with a minimal syntax (with short_open_tag, that is) but I was forever bound to PHP’s parser and request lifecycle. Herein lies PHPTI’s greatest strength and greatest weakness.
I wanted all template blocks defined in a single file. Having them in separate files, which is how CakePHP implemented template inheritance (and maybe still does), was not an option for me. Also, I wanted the template to execute in the caller’s scope (usually the global scope) so that the template “variables” could simply be PHP variables that were set beforehand. The only way to satisfy these requirements was through the use of output buffers.
The output buffer implementation proved to be a little awkward to the end-developer. First off, the developer has to realize that all of their blocks will be executed, even when an overridden block’s contents will be thrown away. Also, it was unfortunate but necessary to expose certain buffer-related hooks like flushblocks and blockbase.
Also, there seemed to be a little contention around how PHPTI’s API was exposed. I chose to use global functions like startblock/endblock because minimal-looking code was the highest priority to me. Others would have preferred to use static class functions or object methods of a global. PHP 5.3 introduced namespaces, but importing all the functions manually at the top of each template file seemed like unsightly boilerplate. In summary, I couldn’t really find a solution that pleased everyone (or even most people).
All these little warts made me slowly realize that PHP was not the best medium to implement template inheritance in. Was a 3rd-party non-PHP template language the better alternative? Traditionally, I had been a PHP purist in this regard. I liked that no additional language needed to be learnt and no context switching needed to take place. I also liked that you got PHP’s standard library, most importantly the string functions, for free.
However, I’ve recently been a convert to the opposite camp. There are just too many downsides to the straight-PHP approach. Escaping input is inconvenient (and more importantly, not default behavior). There is no way to prevent “logic” from creeping into the template layer. And most relevant to us, you can’t extend the language to do cool things cleanly, like template inheritance.
Anyways, when thinking about PHPTI’s future, these were the internal conversations I had. But this doesn’t have to be the end. If you have any inquiries about continuing PHPTI’s development in any way, shape, or form, please contact me. In the meantime, I will be focusing my attention on other open source projects, namely FullCalendar.