A couple days ago I was booking myself some air travel. I finished filling out all the forms and submitted my payment info and finally it dropped me on the confirmation page. The confirmation itself was tiny, and the rest of the page was taken up by hotel offers, several of which were stupid expensive for non-business travel. Most were in the $100s, but one was $239. The full header text on the hotel module read, "only $239 more per night" and that 1) seemed like a fucking nonsense way to describe $239, and 2) got me thinking about templates.
I don't know how the travel site does their templates. Probably on the server, since that's the way most sites still do them. It doesn't really matter, though, whether it's client-side or server-side. There's an opportunity to not say "only $239" and instead say "on sale for $239" or "a hell of a deal for $239" or something that sounds slightly less ridiculous and emphasizes that the hotel's best feature is not its price but like the twice-daily full-body massage and salt scrub you better get for $239. However, to do something like that would mean introducing extra logic. Not logic about data, like is this price part of a sale that will expire halfway through the user's stay, or is this hotel also right by a convention center, but logic about how the data is displayed. So I can kind of sympathize with whoever did not put something like that into the template for the hotel module, because that particular grey area gives me fits.
As part of trying to push client-side templates down everyone's throat at my last job, I started relying heavily on the concept of a view model - an additional layer between the template and its data that prepares all that data to be rendered. And I loathed the sort of things I was creating properties for in the view model, things like the plural form of words or what text to display if some array of objects was empty. Mostly, I loathed the fact that no matter how many fucking view model properties you create, at some point, if you want to keep your HTML in your HTML, you're going to have to put logic in there and that's just that. I loathed the feeling that trying to do a sincere and thorough job of "separating concerns" was tantamount to pushing a big damn boulder up a steep hill.
I have been doing this computer science shit for a long-ass time. I studied it in school for four years. I cannot think of any real world system I've seen in that time that achieves perfect separation of concerns. I posit that the reason for that is that separation of concerns is bullshit.
Hundreds of years ago, our superstitious ancestors would tell their willful offspring stories about monsters and demons to try and trick them into behaving in a way that an admonishment to be careful alone would not. Separation of concerns, I think, serves much the same role for developers. As a concept, it keeps us in line and without that principle our code, collectively, would without question be much more fucked. For the most part, we stick as close as we can to the protection separation of concerns offers us from the giant scary "these concerns are not separate" boogeyman who lives in the forest. But, y'all, there is no concerns-not-separate boogeyman. There is only trying hard to write nice code, or not.
Back to templates. If you count all the client-side templating engines you know of, I bet you run out of fingers. Most of them do the same thing, so why are there so goddamned many? I blame the separation of concerns mythology. Everybody wants a damn logicless templating system and as far as I can tell, no one has managed to invent one or will ever manage to invent one. The ones that describe themselves as logicless continue to have basic operators that perform logical tasks. The ones that do nothing but plug in properties or the output of functions merely necessitate the offloading of all the logic to an additional view model, and since they can't function without that piece of the equation, I'd say they still fail to be logicless. HTML is your logicless templating engine. As soon as you begin adding dynamic information, you can kiss logicless goodbye, because logic is where dynamic pieces of a display come from.
I'm not saying that you can't abstract every piece of display logic out into a view model. You absolutely can, and I will totally come bring you flowers in the nuthouse when you get all done with that. But you don't change anything in doing so. One argument people like to make is that removing logic makes it possible for non-developer designers to work with the HTML, which is - sorry guys - horseshit. If your designer understands the best practices of good HTML, if he or she can do the necessary pattern matching and visualization, he or she can grasp what is template syntax and what is not and move those bits around and not break them, etc. If he or she does not, you're going to be adding the dynamic data after they put their HTML together in Dreamweaver anyway.
There are a few template solutions that try to get around this problem by avoiding template syntax altogether and just using existing attributes of HTML. As far as I'm concerned, that's the same damn thing, just as fragile and problematic, only with the additional penalty of having all the template infrastructure continue to exist in the final rendered product. If your designer can fuck up a template tag, they can fuck up a CSS class or data attribute.
So here's the thing. The concerns that we work so hard to separate are intrinsically linked. It's not impossible to abstract them away from each other, but they still maintain some awareness of each other. The view - the HTML - cannot be separated from the data in contains. It's not an empty vessel that can be filled with anything, it's marked up to have semantic meaning and an appearance that increases the utility of the data displayed. You show me a completely dumb view and I will show you an interface that fucking sucks. There should be logic in HTML, if the HTML isn't static. It should react to its contents and show different things in different ways. When the changes are big, hell yes, create different templates and let the controller determine which to display. But I firmly believe that, when you get down to things like replacing the word "only" with something that makes more sense, trying to achieve perfect granularity is going to make you crazy and offer very little payoff.
Something that is "only" $239 is not a different type of object than something that is "on sale for" $239. It's not in a different state. It's stored in the same table in some database. The same type of object carries it around on the backend adding properties to it. It's delivered to the client with the same JSON structure. It's displayed using the same markup and the same styling. The only difference is a couple of words, words that don't affect the data, that have been pulled out specifically for the purposes of display. Why not let the fucking template handle that? There are plenty of other places that logic could go, but ultimately it's a view model or the view itself. I'm tired of adding tiny little things like that to view models, or worse, creating view models specifically for them.
Separation of concerns is a fantasy. It's a very useful fantasy that guides us to produce better code, but like all fantasies it's still fundamentally bullshit. From now on, when the only reason someone can give me for doing something or not doing something is, "But separation of concerns.. !" I'm going to start calling that what it is.