At a conference I recently attended, two separate topics related to templates sparked a debate off-stage about Logic vs No-logic View Templates. Folks were very passionate about the side they represented. Those discussions were the high point of the conference, since I learned much more from them than from the sessions that were presented.
While everyone involved in the debates had different opinions about the ideal templating solution, we all agreed that templates should…
- not include business logic
- not include a lot of logic
- be easy to read
- be easy to maintain
In this post I’ll describe what I prefer–rules, best practices, performance considerations, etc. aside. My preferences come from my experience with templates for medium to complex applications.
Full-of-logic, logic-less, and less-logic solutions
Before I go into the details, I would like to make one thing very clear. Although I’m trying to make a case against logic-less templates, that does not mean that I am advocating the other extreme–i.e., a templating language that allows a lot of logic. I find such templating languages, especially those that allow the host programming languages to be used inside the template, to be hard to read, hard to maintain, and simply a bad choice. A JSP template with Java code in it and an Underscore template with JavaScript in it both fall into the category of being a full-of-logic template. JSP and Underscore are not necessarily at fault here; rather, developers often abuse the additional freedom such solutions offer.
What I am advocating is “less-logic” templates in place of “logic-less” templates (thanks, Veena Basavaraj (@vybs), for the term “less-logic templates”!).
Good and great templating languages
A good templating language should offer, at a minimum, the following features:
- Clean and easy-to-read syntax (including the freedom to use whitespace that will not show up in output)
- Structural logic like conditionals, iterations/loops, recursions, etc.
- Text/Token replacement
- Includes
A great templating language should also offer the following features:
- Ability to be rendered on the server and the client
- Easy learning curve with as few new concepts as possible
- Simple template inheritance
- Easy debugging
- Great error reporting (line numbers, friendly messages, etc.)
- Extensibility and customizability
- Localization support
- Resource URL management for images, scripts, and CSS
The case against logic-less templates
I consider a logic-less template to be too rigid and hard to work with due to the restrictions it imposes. More specifically, here are the reasons I am not a big fan of logic-less templates:
- Writing a logic-less template requires a bloated view model with comprehensive getters for the raw data. As a result, a messy and difficult-to-maintain view model usually accompanies logic-less templates.
- Every new variation to the view requires updating both the view model and the template. This holds true even for simple variations.
- Getting the data ready for the template requires too much data “massaging.”
- Offsetting the rules of a logic-less template requires a lot of helper methods.
Regarding the argument of better performance with logic-less templates: While they might have a simpler implementation, they require additional preprocessing/massaging of the data. You therefore have to pay a price before the data gets to the template renderer. Granted, a templating language that allows more logic might have a more complex implementation; however, if the compiler is implemented correctly, then it can still produce very efficient compiled code. For these reasons, I would argue that a solution involving templates with more logic will often outperform a similar solution based on logic-less templates.
Conclusion
No doubt, there are advantages like simplicity and readability associated with logic-less templates such as Mustache. And arguably, there could be some performance gains. However, in practice I do not think these tradeoffs are enough to justify logic-less templates.
Logic in a template isn’t really a bad thing, as long as it doesn’t compromise the template’s readability and maintainability.
And as an aside, I’m definitely in favor of more debates than sessions in future conferences, since we actually learn more by hearing multiple viewpoints.
I welcome your thoughts!
Credits: Many thanks to my colleague Patrick Steele-Idem (@psteeleidem) for helping me write this post. He is working on some cool solutions like a new templating language; be sure to check them out when they are open-sourced.

{ 7 comments… read them below or add one }
If your template variables are html, or you’re nesting little sub-templates of html snippets, the templating language has failed at the very thing it exists for. On the other hand, PHP is worse.
Why do you have a “view model”? You service layer should be returning data models, or possibly even raw data transfer objects, that you can use directly without having to wrap them in something else.
You comment about view models reminds me of ORM developers. Not “developers who use ORMs” but rather developers who only think in terms of ORMs. The kind of people who call SELECT * on the database to populate heavy weight entities, then map those entities to models, and then map the models into view-models. Each step of the way a bit more information is lost, information that should have never been read from the database.
Now I don’t mean to accuse you of that, I’m just saying that’s the connotation the term is starting to develop.
It is a not always feasible to design a one-size-fits-all service-layer and sometimes the data needs to be massaged before it is passed to the template for rendering to HTML. Things like ql.io (a data orchestrator) can help, but there is is often certain derived information that the service layer should not be providing in returned data. For example, if the service layer returns data that includes the ending date for an auction then it doesn’t make sense for the the service layer to also include the “time remaining” since that is derived data. If the time remaining time needs to be displayed to the user then that information can be added to the view model passed to a template via a front-end controller. In addition, the service layer should not typically be formatting data (dates, currencies, numbers, etc.) because then that restricts how the client can present the data since the data has already been pre-formatted. Therefore, the front-end controller might need to populate the view model with formatted data. Another option, for richer templating languages, is to provide directives in the template that perform the formatting.
Huh? Mustache cannot be a “logic-less” templating language. The very example they give in their man page ( http://mustache.github.com/mustache.5.html) shows a test construct (the in_ca value).
I think that what Mustache calls “logic-less” is not really logic-less, but rather a *very* limited number of tags and no support for complex expressions (only simple property references). The result of these restrictions is that more view code must be written to populate a view model.
I think it is helpful to show comparisons of “logic-less” versus “more logic” so I created the following Gist:
https://gist.github.com/3125854
I think the code samples with more logic are as easy or easier to read and maintain as the “logic-less” sample. In addition, for the “logic-less” example, the view is required to populate the view model with the following properties:
- cartEmpty
- cartNotEmpty
- cartItems
In comparison, in the case of the the “more logic” examples, the view is only required to populate the view model with a single “cart” object that has “isEmpty” and “getItems” functions as properties. Allowing complex expressions results in less massaging of data by the view.
Having a richer templating language is not necessarily a bad thing. Even with a richer templating language, a developer can optionally choose to code with the restrictions that “logic-less” languages automatically impose, but it is opt-in and not a forced decision.
Mustache (and Handlebars which is more popular) are considered logic-less in the respect that you aren’t writing Application Business Logic into the view itself.
Compare that to an ERB or JSP template where you can write anything you want, in the same language as the application code… and so people invariably do.
They don’t however mean you don’t use logical constructs for presentation. I will frequently write a Handlerbars helper to format some html in a particular way to fit the UI design (eg. render a span containing a value to 2 decimal places, with classes for right aligned and making the text red if negative).
Hi..
Writing a logic-less template require a overstuffed view model with complete getters for the raw data. As a result, a messy and difficult-to-maintain view model usually accompany logic-less templates.
groupon software