Building simplicidade.org: notes, projects, and occasional rants

Template systems

I have a love/hate relationship with Template systems for quite some time. The following is a brain-dump about where I stand right now regarding which system to use in the E5 project.

When I started using them at work (circa 1998 or 99) the goal was simple: separate programmers logic from the layout so that designers can tweak the templates without breaking the code.

It was a simple and very worthwhile goal. And for the most part, it worked. You still need to coordinate which templates will be created, and how will the page be broken up into pieces to enable reuse of common parts, but it mostly worked.

The template systems where designed to be used by web designers, and given that those where accustomed to HTML tags, the more powerful template system that needed loops and decision constructs opted to create those with a simple syntax. The template systems became domain specific languages (DSL).

But, with the improvement of the HTML, CSS and JS capabilities, I don't know if the designers are still the target audience of template systems. As I split a set of HTML pages into a set of reusable templates, I try to create blocks that make sense in terms of caching, data-store life cycles, and other subtle factors that a web designer just doesn't care about. The page breakout is becoming a engineering exercise.

As programmers/engineers, we don't need the comfy world of a DSL. We want to work in the same language that we use to code. Templates are, at most, a small macro language that gets compiled into source code, in the same language that we have the rest of the system.

So I'm starting to move away from Template Toolkit, my preferred template system, into something that uses native Perl as the DSL. I don't know where I'll end up yet. I'm looking at Tenjin, Text::MicroMason, and Mojo::Template. There aren't many template systems that use Perl as the control language, actually.

The first two should be the most stable ones, older ones. Tenjin is also the fastest template system I've tested, although speed wouldn't be a deal breaker.

Controller-centric or View-centric render process

But we can't judge template systems without considering where and how they will be used. In my case they will the last step of a web request, handled by a web framework.

I'll use a BBC site page to illustrate my current dilemma, an article about Wikipedia page controls. Things of interest to me:

  • the central part of the page is the main content, and directly related the the URL. This is the content that you came here to get. It has a lot of HTML before and after that are present to add value to the site (we hope), and provide exit destinations (the navigation and related stories);
  • the title of the page, early in the HTML, is also directly related to the URL and the story: this is important because the template system must support inside-out rendering (first the central part, and then the wrappers), or have all the information in memory before starting the render process;
  • some parts (the header, footer, and left-hand sidebar) are mostly static, and with low or no relation to the main content: in this case only the category of the article influences the navigation. It might also influence the related BBC sites;
  • the right-hand side shows related stories. The "related" part might be highly dynamic, or static per category or a mix in between. The related external links are probably part of the story.

The path for a typical request (like /2/hi/technology/8220220.stm) looks like this:

  1. collect all the important data from the URL: in this case the it seems to react to the hi/low part to pick the version of the master template, the category (controls the right-hand side column) and the article ID;
  2. fetch the correct article and related informations (author, publish date, picture URL, caption...);
  3. fetch the related articles for the right-hand sidebar;
  4. call the view renderer with all of this.

Pretty basic and straight forward. Steps 1, 2 and 4 don't pose to many questions, they are required on any pipeline I can think of.

But the proper way to do 3 is a matter of discussion. On one hand you can put enough information on the URL to decide what the right-hand sidebar needs and fetch it in with some calls inside the Controller (I'm assuming here a MVC-style framework). In this model the controller prepares everything that we need to display the page.

But this makes the view a bit inflexible because if we need to had another box the top or bottom of the page, we would need to tweak the controller code.

On the other hand if our template system is powerful enough, we can have a small API that we can call back into Perl land, and have these little reusable boxes generated for us. The view controls the entire process of display.

The advantage of having a decent view system, even a object oriented view framework, is the extensibility that you get. Imagine a Moose-based template system: view are classes that you can extend, override, add before and after processing. Rendering is just creating an instance and calling a small method, as_string() or even stream_to_socket().

A system that brings the full power of Perl to the template world is Template::Declare. It treats templates as classes that you can subclass and extend. It seems very similar to what I like but I have zero experience with it so far.

No decisions have been made yet. I need to evaluate Template::Declare and see if it really fits my brain.