Why I don't like HTML surrogate template engines > stdout.in Ievgen Kuzminov IT blog

Why I don't like HTML surrogate template engines

Feb 3, 2016, 3:13:53 PM

Preamble

Mostly it is about template engines (that hide away real HTML) in Ruby (as due to app runtime specific it is very easy to add pre-compiled "sweets" there, and everybody do it). But in general such tpl engines could exist in any server side language.
I don't like DSLs and abstractions that lead me away from the "origin". Ok, a careful reader have already got what will I write further :)
This post is not about "stop using it" or "it is bad", it is about "reconsider is it really so useful".

Let's start with examples

This just a small subset of all existing engines, that I have herd of, just to have an examples. Each language has it's specific, but mostly script web languages are good template engenes by themselves.

And I am really absolutely fine with most of them. Except those that force own HTML-replacement surrogate (it is Slim, HAML or JADE like).

 body
    h1 Markup examples

    #content
      p This example shows you how a basic Slim file looks like.

      == yield

      - unless items.empty?
        table
          - items.each do |item|
            tr
              td.name = item.name
              td.price = item.price
      - else
        p
         | No items found.  Please add some inventory.
           Thank you!

And now I'll try to explain this...

What template engine should do

  • Give clear way to mix HTML and code / variables (first of all!)
  • Support basic var output, loops and logic statements
  • Encourage to write clear markup
  • Encourage to avoid any logic inside the template (of course all of us know, that we can not avoid logic at all, but at least it should be consciously)

But let's face the truth

  • We do not need to invent the wheel (instead of HTML) to achieve it (ERB/Mustache like templates just give us all required features, the rest of things are in our hands).

  • This is not the Template Engine - that restricts a Coder from doing "bad things" in the Template. It is a Pragmatic Coder - who understands what he is doing and restricts himself! We are using tools the right way, not the tools pushing us around!

  • It can "swallow" the error inside the code or even mislead by stopping error trace on tpl line (while there could be deep and unclear code trace inside model call)

  • HTML surrogate - force you to learn it's own syntax. It pretends to be "very similar" to native, but the scariest thing - it has it's own flows and pitfalls, that you need to learn all over again (in addition to HTML's imperfection)

  • Have you ever done complex markup? Maybe you have a dedicated markup developer in your team... do you ask him to learn HAML or you convert every tiny markup fix from HTML to HAML yourself ?

  • Some space/indentation dependent tpl engines breaks the way you used to format HTML code (I hope you do it automatically via IDE)

  • The farer you are from native HTML, the more complexity you add. I do not want to care about non-standard things, my HTML knowledges are relevant ALL OVER the web dev world. My %you_cool_template_engine% knowledges are relevant only on a small subset of web dev where this technology is used. I clearly do not want to share my lifetime on that. Web dev is evolving so fast, that we just can't tight ourselves to some particular technology. Only cross-platform standards allow us to keep our knowledges at least semi-relevant. Don't became a slave of some programming language, framework etc.

So you are saying all pre-processors are bad ?

Of course you can point me other examples of common web technologies that also have widly used pre-processors. And for some reasons I do not have objections on that. But they are also guiding developer far from "origin". They are CoffeeScript, Sass, ES6/Babel etc.

Pre-processor (template system) should solve some problem to have a right to be in use.

  • Sass/Scss - solves a huge issue in CSS - introduces variables and structuring/inheritance.
  • CoffeeScript - it was "fixing" pure JS before ES6, now I doubt it is needed...
  • ES6 via Babel - it is clearly a "pre-compiled surrogate", but the thing is... it is a future standard. I am not doing something irrelevant to native JS. I am not trying to "escape JS", I am just using the "future JS". It is completely different.
  • Slim, HAML etc. - gives you a way "not to write a closing tag" ... that's a weak plus as for me.

Breaking an illusion: wrong issues - wrong solutions

Mostly introduction of sophisiticated template engines seems to be cool not because of the simplified HTML syntax. But because of the ways to add more complex logic into the template in a "more elegant way" (i.e. with less code) via different Modifiers, Filters etc. It creates an illusion that you do not introduce a lot of logic complexity inside the tpl. Instead of making real segregation of concerns and introducing clear View Model layer, we hide the dust under the carpet!

Don't you see that somethign is broken with this approach ?

Solution: Use your IDE and Emmet

You can save some typing time with Emmet. It is supported by almost all code editors.
As easy as type this

div>ul>li

to produce this

<div>
    <ul>
        <li></li>
    </ul>
</div>

It really speed up markup design.
Also modern IDEs close tags automatically or rename paired tag.

Solution: View layer design

As for organizing logic and keeping it out of the template. Do not wait tpl engine to do it. Just introduce ViewModel and Representer concepts into your app. It is not only clean up the View template, but makes code isolated and more testable.

Refere these Ruby solutions as a great examples:

Conclusion

I am almoust sure - some "rocket science" Temaplate Engine or HTML pre-processor "is not the solution you are looking for" (C). It is very likely other solutions will bring much more profit to your web app, while keeping it "close to the origins".

And please - spend your time only on relevant knowledge and techniques ;)

comments powered by Disqus
Ievgen
Kuzminov "iJackUA"
Web Team Lead
at MobiDev (Kharkiv, Ukraine)
Code in Ruby and Elixir, but still love PHP. Explore ES6 and Vue.js. Explore databases, use Ubuntu and MacOS, think about IT people and management

Notes


At last I have just got the difference between Dependency Injection and Service Locator (I really hope so :) ). Hallelujah ! And now it is clear what is Inversion of Control. That worth all these years in programming...



First "real" visitors on blog from search and soc nets today (not only my friends and colleagues) ! Hello Italy and Norway ! :)



Dev stack abbreviations became more and more popular (MEAN vs LAMP etc.), StrongLoop introduces BACN - stack for mobile applications.