I created a brand new, lightweight template engine. I immediately received a flood of comments from friends and from other developers as to why I would re-invent the wheel and develop yet another template engine. However, despite all of the wonderful options in existence, they all seemed to be solving a slightly different problem than the ones I was trying to address. They look great on paper, and in practice, they are. But there are situations that simply need something more streamlined. And that’s what a template engine does best: Streamlines the design process.
So, what is a template engine?
Web pages are always served to the browser in the form of HTML documents. What isn’t so visible is the backend logic to generate this page. In many cases, the logic is very simple and the page is nearly static (almost fully pregenerated). In other cases, it’s generated on the fly by a CMS (such as WordPress) and can change on each page load.
It’s a general rule of thumb to keep your HTML separate from your PHP. Your program logic should not be intermingled directly with your presentation logic, so to speak. In other words, you should have all your HTML separated from your application, in its own template file. They should be two separate systems, intermingled by function, not by form.
This is important because it allows changes to the application logic to be fully decoupled from changes to the website’s design. It also allows new themes/designs to operate completely independently of the application logic itself. Management is easy with a properly decoupled architecture.
Two Schools of Thought.
In the PHP templating realm, there are two widely held views that arise. These two views both have passionate adherents who will provide a multitude of reasons for their opinions. And in a sense, neither is wrong.
- Have a highly advanced template engine and store a large amount of logic directly within HTML files.
- Use RAW PHP and the “bare-metal” tools available.
The first school of thought has largely become the industry standard. Most applications are bundled with highly robust, professionally maintained engines. However, as it turns out, the second school of thought has not totally fallen by the wayside. PHP is (quite literally) a legitimate template engine all on its own. It’s hard to discuss native templates without someone quickly mentioning PHP’s competence for the job (or lack thereof). In fact, native, raw templates can do almost anything that the world-renowned players such as Twig can (albeit with messier syntax). These template engines don’t provide new functionality as much as they provide a wealth of convenience. And in their convenience is their value.
The advanced template engines of the modern day (Twig, Blade, Smarty, and so forth) did not arise in a vacuum. They serve an immensely useful purpose, and are extremely powerful tools for any web developer. They allow the design workflow to be seamlessly developed without refactoring application code, giving developeres and designers alike the freedom to create captivating websites for the 21st century.
But there are many mature options on the market. So many that the choices are practically endless. It’s hard to imagine any application need that cannot be covered generously by multiple widely respected open-source projects. With such a market saturation, it seems laughable to delve into a “solved problem” and to tackle the problem with a fresh set of eyes. But that’s exactly what I endeavored to do. And this post will discuss exactly why.
The nature of Too Much Syntax.
The value of a modern template engine is in its convenience. There is very little that a raw PHP template can’t do. Albeit, probably with difficulty, but it’d be possible.
There are a handful of basic principles I follow when designing templates:
- I should be focused solely on design and presentation. The goal should be theme/layout work
- The logic should exist if it’s needed. More advanced logic should go into the PHP code, not the template.
- Syntax must be readily easy to read and write.
- The template engine must not be a language within a language.
- The template engine must be lightweight.
With these criteria, I came up with a small list of features that were essential.
- Loops. These are highly useful for almost any template.
- Basic If/ Else if / Else expressions
- Language variables
- Standard variables
- Simple inheritance (load a template that loads other templates)
- Listeners & Events (hooks that allow menu links, header blocks, etc to be added on the fly)
- Auto escaping (XSS prevention)
- Fast performance
Addressing Software Bloat
Unfortunately, it seemed that the most mature template engines of the market actually fit the bill the least. They were practically programming languages. And not small ones. They had a multitude of complex syntax structures to learn.
Over time, I found myself designing my application around my template engine, rather than utilizing the template engine for my application. I found this to be concerning and detrimental to my development workflow. As important as presentation is, the application itself can be presented multiple ways, and should be presentation-agnostic. Unfortunately, I found that the most advanced template engines on the market were the least platform-agnostic in terms of general presentation principles. The entire application ended up being heavily designed around the syntax of the template.
In with the New
I solved this problem by writing an entirely new engine from scratch. It is streamlined, fast, and simple. It has the features that I needed most, and was designed specifically around the workflow of my applications. The end result:
- 166 lines of code.
- Feature packed template engine with simple syntax
- Lightning fast parser/compiler – caches templates for native execution
- 6.55KB of code
And it featured all of the constructs that were necessary. Template backreferences (my implementation of inheritance), loops, if/else blocks, language strings, standard variables, auto escaping, and a built in compiler were all implemented all within one tiny 6.55KB, 166 line file.
It had convenience. Enough to allow me to focus on design. And perhaps its best selling point was that it let PHP do what PHP does best: evaluate code.
In fact, the engine has a direct compiler to convert pretty syntax to PHP-native syntax. It is, in essense, a compiler to generate native, raw PHP templates. This allows the syntax to stay relatively close to the application logic paradigms that PHP tends to follow, keeping the format familiar and easy to understand. It also allowed the template engine to be fast and feature-packed without becoming bloated.
So far, it has served me well. I am currently working on multiple projects to employ my brand new template engine. And it has saved me time and allowed me to focus on what I enjoy most: Development.
I encourage others to check out similar template engines for simple development projects. They are often easy to integrate, lightweight, and feature packed. If you need ideas or a place to start, you are welcome to check out our own homegrown engine on Github. It has everything you need, sells you the convenience you want most, and gets out of your way for the rest.
Check out Simple Templates on GitHub!