What is the programming rationale of logic-less templates (as in mustache/handlebars)? Why is purposely limiting the capabilities of the template language considered a good and desirable design pattern by the makers and users of these logic-less template libraries?
I've been working with node.js and handlebars lately on a small project and I find I'm regularly stymied by the lack of simple logic in handlebars templates.
Before I ditch the handlebars template engine in search of one that has greater logic capabilities, I'd like to understand the programming rationale behind using a logic-less template language.
I should clarify that I'm not asking for people's opinions on which kind of template language is better. I'm asking what are the objective reasons that people designed, built and use logic-less templates.
Here's a fairly simple example of what I would like the template to be able to handle by itself, but I don't see how in handlebars so I don't understand why it's considered a desirable characteristic that the "logic-less" template can't handle such a simple UI presentation by itself. Since there are a number of logic-less template choices, I am assuming there are useful reasons for it that I'd like to understand.
I have two variables from may app state that are passed to the template:
fanOn // boolean: true or false
fanControl // three states: "on", "off", "auto"
fanOn represents the current state on or off of some fans I am controlling
fanControl describes what kind of control mode the fans are in. "on" means they are turned manually on and will stay that way until further notice. "off" means they are turned manually off and will stay that way until further notice. "auto" means they are under automatic thermostatic/software control.
If the fans are on, I want to display a button to manually turn them off.
If the fans are off, I want to display a button to manually turn them on.
If the fanControl setting is on or off, I want to display a button to set it back to auto.
So, there's always a "Turn On" or "Turn off" button and if it's not in "auto" mode, there's a "Set Back to Auto" button.
There's no business logic here, it's just a matter of building the proper presentation based on the current state.
Here are various references I've found on the topic (which contain a combination of opinion and fact - a reader has to sort out which is which):
There is a tendency, especially with inexperienced programmers, for people to include business logic in templates. This is generally considered bad practice and an anti-pattern. Business logic belongs in the model layer and should not have anything to do with presentation/view layer.
Taken to the extreme you'd end up with PHP - where 100% of all code, business logic, controller glue and views are embedded in HTML.
To discourage this, logicless templates were developed so that junior developers can't accidentally include business logic in the view layer easily.
For really good separation of concerns (single responsibility) checking for values in order to decide what to print on screen is not the responsibility of the view layer. It should be done in the controller. However, there are times when it really shouldn't be the job of the controller (when using compound UI elements made up of primitive elements for example, the checking may be part of the implementation detail). For those use cases it is often useful for templating libraries to provide workarounds such as helper methods. But such use cases should be rare.
If you keep having to write helper methods it may be you're just not used to separating controller logic from presentation logic. As such, some of the more extreme logicless templating languages such as Google's ctemplate doesn't even provide such workarounds (note that ctemplate predates a lot of the newer logicless templating languages).
Newer developments of logicless languages are even more extreme - templateless languages. Where the templating language has no language at all and you just pass the correct JSON data (or other structured data) and the templating engine will find the matching HTML elements with the correct id or class name to inject values into.
After researching a bunch of other template languages, it appears that there are basically three schools of thought and you really have to decide which one lines up best with your development philosophy, team situation and project needs.
Option #1: Templates have a full-blown programming language in them (e.g. PHP).
Option #2: Templates are logic-less (e.g. Mustache/Handlebars).
Option #3: Templates have some capability to make presentation-focused logic decisions (e.g Dust).
The PHP model exists and works. Without proper discipline, presentation and business logic can get very intertwined making an untestable mess. This doesn't mean that good discipline and proper techniques can't lead to a clean implementation, but it is also easy to shoot one's self in the foot with improper practices.
Perhaps as a reaction to the mess that can be caused by this and some of the ensuing debate, the notion of logic-less templates arrived. Zero business logic can ever get put into a logic-less template. But, because there is no logic in the templates, there must be another layer of code somewhere that makes presentation logic decisions and preconditions the data sent to the template so that it perfectly aligns with the chosen UI design. This requires a separate place for presentation logic code. Without proper discipline or understanding, this code gets intermingled with the business logic and this code often has to be modified to make fairly simple changes to the UI design in the templates. The undisciplined case is perhaps not as messy as with Option #1, but still some don't think this is ideal either - others seem to like it.
A third option is templates that attempt to expose enough logic to make presentation-based decisions based on screen size, based on state of the data, which radio button to select, which buttons to display, etc... but still keep that separate from any business logic in the main app. Plus, this can allow a person of different skills (e.g. a UI designer) more complete control over the presentation without involving a javascript programmer from the main server-side app.
As with many tools, one can argue advantages and disadvantages of each approach and there are never absolute right or wrong answers.
In search of templates that were more in line with option #3, I came across Dust (used by LinkedIn) and Walrus and Nunjucks with these blurbs in their documentation that helped describe their goal in relation to option #3:
From Walrus:
View logic is different than business logic (and that's okay!). In modern web apps, there's often a good amount of presentation logic involved. This logic doesn't belong in your application code, your backbone models, or anywhere else but the presentation layer. The templating language is a good place to put this.
And, from Dust:
Logic in Templates
Templates with logic versus "logic-less" templates is a hotly debated point among template language designer and users. Dust straddles the divide by adopting a "less logic" stance. We all know that real business logic does not belong in the presentation layer, but what about simple presentation-oriented things like coloring alternate rows in table or marking the selected option in a dropdown? It seems equally wrong to ask the controller/business logic code to compute these down to simple booleans in order to reduce the logic in the presentation template. This route just lead to polluting the business layer code with presentation-oriented logic. Dust provides some simple logic mechanisms and trusts you to be sensible in minimizing the logic in your templates to only deal with presentation-oriented decisions. That said, let's take a look at the ways Dust let's you have logic.