eBay Tech Blog

The Case Against Logic-less Templates

by Sathish Pottavathini on 10/01/2012

in Software Engineering

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:

  1. Clean and easy-to-read syntax (including the freedom to use whitespace that will not show up in output)
  2. Structural logic like conditionals, iterations/loops, recursions, etc.
  3. Text/Token replacement
  4. Includes

A great templating language should also offer the following features:

  1. Ability to be rendered on the server and the client
  2. Easy learning curve with as few new concepts as possible
  3. Simple template inheritance
  4. Easy debugging
  5. Great error reporting (line numbers, friendly messages, etc.)
  6. Extensibility and customizability
  7. Localization support
  8. 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.

{ 10 comments… read them below or add one }

rupa October 5, 2012 at 11:09PM

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.

Reply

Jonathan Allen October 5, 2012 at 11:47PM

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.

Reply

Patrick Steele-Idem October 9, 2012 at 7:57PM

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.

Reply

dc October 8, 2012 at 11:30PM

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).

Reply

Patrick Steele-Idem October 9, 2012 at 7:59PM

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.

Reply

Brad October 9, 2012 at 2:07PM

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).

Reply

Jaime March 5, 2014 at 6:05AM

“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.”

So you are admitting the problem is not the language, but bad development practices by people.

Reply

Taylor November 4, 2012 at 9:55PM

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

Reply

Mateusz Szczap November 6, 2013 at 7:56AM

At mobile.de (owned by eBay Inc.) we have a lot of legacy FreeMarker code which contains lots of more business logic than it does.

We have decided a logicless (or maybe not so logicless) templates a go, we selected Google Closure and developed now two applications in it.

I think it is unfair to put all logicless template engines into one bucket because Google Closure Soy Templates give us a minimal set of operations we can perform. The former example on the gist showed that in case of one logicless templates one doesn’t even have if statement.

Google Closure Soy provide if..
https://developers.google.com/closure/templates/docs/commands#if

Still our new soy files are very clean, we have a view model but we do not think it is wrong, in fact it is a famous “presentation model pattern” from martin Fowler, which to my knowledge has not yet been called an anti-pattern :)

It looks like other companies such as LinkedIn are also moving towards this direction, they use another logic-less templates, called dustjs, which are also not that logicless after all.

So far I like logicless templates such as Google Closure Soy and I recommend them, we have to plans to go back to FreeMarker hell.

Mind you there is a very important case here about Unit Testing, which should rather be done in the backend code rather than in Frontend (which is also possible I know).

I also want to mention that polimorphism and injecting a different implementation of a view should be done in the backend and is sometimes required and necessary otherwise it leads to messy code.

Naturally you can keep even FreeMarkers templates very simple, it just turns out on the large code bases people won’t and you cannot easily police that.

Reply

nick February 15, 2014 at 12:30PM

In the interest of the community in the ease of templates and logic I would like to state my case. We have server side business logic to group data into a complex object. Once this object is done, we then render the object into a view that is rendered using Razor. The next step is we then parse this client side data using our templates to present html data differently based on logic, a href, span, div for example. I am finding it impossible to maintain two pieces concurrently when a higher level logic changes how the whole product is presented, meaning a column being added or name changed or another entity entirely. Maintaining workflow inside of a template is the end result but is not the real answer because the right questions were not asked yet.

Reply

Leave a Comment

{ 3 trackbacks }

Previous post:

Next post:

Copyright © 2011 eBay Inc. All Rights Reserved - User Agreement - Privacy Policy - Comment Policy