Choosing a template language(s)

Template languages: a densely populated land, where not even angels fear to tread.

Let's rush right in.

Mail merge for web developers.

A template language is mail merge for web developers.

A template language is not a transformational grammar capable of specifying a projection between semantic signals and a diversely formatted symbolic representation.

A template language is for taking crap and pooping it into HTML.

(Pardon my French)

Some template languages are programming languages.

Every template language starts with the basic notion of inserting variable data into a reusable structure.

// C stdio - http://pubs.opengroup.org/onlinepubs/009695399/functions/printf.html
printf("There are %lu lights", num_lights);


# Python - http://docs.python.org/library/stdtypes.html#string-formatting
data = {'verb':"run", 'subject':"refrigerator",}
print "See %(subject)s %(verb)s. %(verb)s, %(subject)s, %(verb)s!" % data


// flatstache.js - https://github.com/natevw/flatstache.js
var data = {thing:"World"};
Flatstache.to_html("Hello, {{ thing }}!", data);

But simple variable replacement isn't enough for most template languages.

The three examples above are just "string formatting", not "template expansion": When num_lights is 1 we should say "light" instead. Maybe we'd like to capitalize a string when we're using it at the beginning of a sentence. Maybe we want to style every other table row with alternating colors, or add a special border to the first and last list items...

<table border='1'>
<tr><th>Name</th><th>Age</th></tr>
<?
$result = mysql_query("SELECT * FROM people");
while ($row = mysql_fetch_array($result)) {
  echo "<tr><td>" . $row['Name'] . "</td><td>" . $row['Age'] . "</td></tr>";
}
?> 
</table>

Some template languages become PHP without the plumber's crack. When they're well-designed, these empower non-"coders" to dabble in programming logic without giving them to much rope to SQL inject themselves with.

A simpler approach?

Other template languages are just template languages.

These are the ones that talk a lot about separating logic from presentation in their documentation. What they mean is, they expect you'll be providing data to your templates via a perfectly good programming language. What they mean is, "you shouldn't expect your template language to do a programming language's work".

Usually these other template languages implement only two logic features: loops and conditionals. The only "programming" the template author can do is declare that certain sections of their template get repeated or left out if certain data has been repeated or left out.

What this means

A template combines variable data with a predefined structure. Taking the programming out of the structure means moving that programming to where the data is gathered.

Unfortunately, in situations where development roles are split between separate teams, this means that the "Frontend" team needs to rely more on the "Backend" team's help.

What else this means

Fortunately, this also means that the "Frontend" team needs to rely more on the "Backend" team's help. This might have some slight productivity drawbacks, but can lead to overall architectural and performance benefits.

Maybe it's only because most programmers aren't people people, but careful "separation of concerns" typically pays dividends wherever it's applied to software. Fetching and manipulating data at a lower level forces everyone to think specifically about what information a given web page really needs, and how that might effect the simplicity or scalability of the system as a whole. (At last year's DjangoCon, we heard some interesting stories about "little" template changes causing an order-of-magnitude more database load.)

Now there's nothing inherently evil about picking a more empowering template language — unless you're "binding" variables into your SQL queries using string concatenation, in which case Dante would like to interview you for a book he's working on.

Better to give a good "Frontend" developer any programming features they need in their template language, than trust a bad "Backend" developer with all the power tools and blasting powder of a bona fide programming language.

What to do about it

It should be clear why there are so very very many different "competing" template engines: every one makes different choices about how a template is defined, and also about what a template can define!

So what should we look for in a template language?

The "perfect blend" will vary from team to team, and even from project to project. But overall, a template language should:

  1. Be easy to implement in and access from the languages that matter these days — For &yet right now that means JavaScript, Python and (in a pinch) Objective-C. Your thing might be Ruby and C#, that's cool too. The obvious point is that if a templating engine would be hard for you to use, it's the wrong one for you to choose. On the flip side: if your Django/Rails/Express/jQuery/framework-thing makes it easy to use one particular built-in template language, that's the one for you.

  2. Encourage thoughtful use of source data — A template language shouldn't tie the hands of its primary users, but it does need to prevent as much fat-fingering as possible. Mistakes like Cross-Site Scripting and SQL injection are unacceptable for most projects. On a few projects, unoptimized database usage could be costly. On all projects, keeping everyone aware of what data is available (and how) is beneficial.

  3. Keep the app as a whole clean and simple — Boring boilerplate code encourages abundant annoying bugs. Any stuff that doesn't make your function, your page or your project special all needs to be typed correctly anyway. So take the "template language" idea of variable data vs. reusable structure, and apply that to your team's work as a whole. Your template language, like any language, should help you simply say what you mean.

At &yet we've used everything from Django's template system (a full-featured engine that mimics Python to good effect) to mustache.js (an intentionally simple language with compatible libraries in many programming languages), and other interesting ones like Jade and Haml (which compile indented structures into HTML). In the future we may find something like Knockout useful. In past lives we've been known to use XSLT and various PHP and ColdFusion solutions to get the job done.

Remember that in the end, your choice of template language is tiny and insignificant compared to, say, your choice of the people you work for and the people you work with. Each templating engine will have its upsides and downsides; being conscious of its overall approach, goals and shortcomings will help you and your team use it most effectively.

You might also enjoy reading: