What bothers me about this and other templating is that branching is so inconspicuous and therefore hides its complexity
.
Lets takes this extended example:
<template>
<div>
<h2 class="c-section-heading">HELLO</h2>
<p>Duis a turpis sed lacus dapibus elementum sed eu lectus.</p>
<p v-if="location.query.home">You specified a home query: {{location.query.home}}</p>
<a v-else v-on:click="specifyHomeQuery" class="u-warn">No home query was specified</a>
</div>
</template>
And compare it to:
<template>
<div>
<h2 class="c-section-heading">HELLO</h2>
<p>Duis a turpis sed lacus dapibus elementum sed eu lectus.</p>
<p>You specified a home query: {{location.query.home}}</p>
<a v-on:click="specifyHomeQuery" class="u-warn">No home query was specified</a>
</div>
</template>
The first one creates a div with 3 children with the type of the last one depending on the condition. The second one creates a div with 4 children (and a warning in the dev console). Both have 4 lines between the <div> with the same content except for two attributes on two elements and are indented the same by convention of the framework. They look nearly identical when quickly parsing over them but results are very different.
Compare this to the other react solutions, or my personal favorite:
const Home = ({location}) => <div>
<h2 className="c-section-heading">HELLO</h2>
<p>Duis a turpis sed lacus dapibus elementum sed eu lectus.</p>
{location.query.home
? <p>You specified a home query: {location.query.home}</p>
: <a onClick={specifyHomeQuery} className="u-warn">No home query was specified.</a>}
</div>
I think it's pretty clear which "templating system" better represents the fact that this has more complexity than just a simple, linear component.
Templates need some level of logic, yes. Putting the entirety of the business logic in your templates is not only bad, but dangerous. Because unless you're replicating your business logic in your non-template code, I can change things in the DOM, and potentially corrupt the system.
Unless I completely miss the boat about how Angular/React/Vue/etc are supposed to be used. I only know from my previous years of seeing it done in the way I mentioned above, and every time, the work always ended up duplicated in the non-template code.
You are plain simply wrong.
First of all, logic in templates is something which is OK to have. Different templates display information in different manners.
Second thing, I don't think you've seen how awful and unmaintained code which manipulates DOM instead of templating looks like.
This is really great to see the emphasis on static vs dynamic parts in templates. Polymer, Glimmer, and some other template systems make the distinction between static and dynamic content, but React and most other vdom libraries don't.
I was looking for options for HTML templating in JS found that JS template literals very naturally separate static and dynamic sections between the literals and expressions. I've been testing a library based on them [1], and for real-world templates with large static sections, it's indeed faster than traditional vdom.
Instead of including if/then/else logic in the template, templates are duplicated for each branch and the logic is pushed up to the controller. This takes on hand-managing duplicate code (because there will discrepancies between the "logged in" and "logged out" version every time someone forgets they need to change two files, or doesn't notice there is a second version to touch) to avoid having any code in templates (which it labels as technical debt without support).
This does not seem like a worthwhile tradeoff to me. And the author doesn't address loops, which often want to have special treatment of first or last elements, even/odd rows, and other small bits of logic. When you combine these things, you're going to have a combinatorial problem, I can just imagine a shopping cart table with templates like shopping_cart_item_list__table_row__last_item__logged_in__even_row__multiple_quantities__discounted_item.html
And what's with the really confrontational tone? This article would've been improved by spending a couple hundred fewer words putting words in the reader's mouth and insulting their tools/code. There's a chance this could be useful in some situations, but I sure don't want to spend any time talking to this guy.
My issue isn't the existance of programmatic expressions (yeah, it's the point of templating languages), but more that the way vue (and angular) do it is a mess of syntaxes that creates a really, really strange template.
The lodash example is the main critique because that is not JS, but it involves evaluating JS - it's created its own programming language with its own rules -- when one was right there from the beginning!
But a template is not "regular old HTML". HTML is a standard for declaring marked up text. What Vue and similar libraries do is make adhoc variants of HTML (all different) with extra looping constructs and if/then constructs and so on. The templates also require embedding snippets of JavaScript code in them -- code which standard JavaScript/TypeScript IDE tools don't know about and so can't refactor, validate, or navigate.
These templates may look declarative because the look HTML-ish but they are not -- because of the embedded code that can call arbitrary functions in your application. The result is hard to debug and reason about. Where do you put a breakpoint in such a template? How do you abstract part of a template into a function? How do you add logging to such templates? How do you know what object is having its data accessed for templating languages like with Angular that do complex contextual lookups behind the scenes? How do you get code coverage reports? How do you get code completion? How do you get precise error reports? And so on. For more on why templates are a bad idea, see: https://blog.dantup.com/2014/08/you-have-ruined-html/
That is why I feel these sorts of template-based approaches will eventually be discarded as obsolete for writing single page applications as web programming continues to progress (in favor of generating UIs directly from code). HTML-ish templates feel familiar to people with experience building progressively enhanced web apps by sprinkling a bit of CSS and JavaScript on top of HTML generated from a server -- but for single-page apps that spend most of their time converting JSON from a server into HTML (or just doing stand-alone activities), a templating HTML-first approach make little sense. You just don't need extra templating machinery that you need to learn and maintain and that just gets in the way of development.
By contrast, consider the HyperScript API for generating HTML from JavaScript/TypeScript (as used in Mithril, Maquette, and optionally in Inferno and some other vdom libraries).
If you use the HyperScript approach (especially with Tachyons.css or similar), you are just writing JavaScript/TypeScript/whatever and can leverage all of the language's features. JavaScript-first for modern SPAs!
Dude... Ridiculously complex logic in the view is like the quintessential problem of templates; this problem is further amplified by the burden of groking the idiosyncrasies of every other self-styled templating API.
I agree that putting all that logic and template vars into a template is confusing. Hard to create mocks of what the HTML should actually be structured like. Im using Jade so I can be terse and pre-compiling the templates. While in my Backbone application, I apply DOM-like rendering with Plates.js.
Templates should be about how things look like. You'll need some minor capabilities to style things dependent on values, but it's a slippery slope: You start out with branch on "exists", then later see that you need to style every even row in a table. Next project you need to style every third row and decide "oh, I can generalize that". And then you end up with a full math implementation. And wouldn't it be awesome if we could branch depending on the length of a value? You start hacking and the next thing you know when you wake up in the morning is that your template language is Turing complete. Now you have another language to learn.
It's far easier to make a cut at "no logic apart from boolean checks" and then use a proper client-side framework such as backbone if you need full view logic on the client. It separates concerns and makes clear where logic is supposed to reside. I love separation of concerns!
The templating is fast and safe but a pain to use. For example, an HTML Select needs a 3-value list: id,text,selected bool. You can't evaluate a comparison (if...) or call a function in the template. It's unpleasant.
I hate template languages myself. But in Svelte’s defence, their template language in version 3 seems to be well-designed and streamlined.
It doesn’t have the ad-hoc nature of “oh crap we forgot to add if-then-else” of Angular or “let’s create half-a-dozen incompatible javascript-like DSLs” of Vue.
I pretty much agree with the reasoning how templating doesn't promote anything other than separation of languages. It always frowned how people emphasised templates being logic-less, which imo oversimplifies the matter.
Yet i still don't seem comfortable writing the markup in js. Even react's JSX preprocessor doesn't seem right to me.
This is actually quite challenging because the template language allows you to insert template tags into any location in the template file, and while people usually put them in reasonable places, there’s no guarantee. For example, someone could do a thing like `{{ less_than }}div class="foo">abc</div>` and that would be totally valid but a nightmare to parse.
That’s different from a more structured template-style language like JSX, where there are only a few valid places to embed JS expressions so it isn’t too challenging to make them all look good.
Being slightly more complicated is a feature, IMO. I always get the impression that the logicless templates end up as quite logicful languages once you add all the control flow directives. But its all very ad hoc so some simple things end up being tricky to do, like passing parameters to a subtemplates or giving different CSS classes to the even and odd rows. If you just use a regular programming language from the start these are just a matter of calling a subroutine or using an if statement instead of being something you will need to go to Stackoverflow to figure out.
I've also seen template hierarchies so deep it was a major effort trying to figure out which template did anything besides forward to another template.
Compare this to the other react solutions, or my personal favorite:
I think it's pretty clear which "templating system" better represents the fact that this has more complexity than just a simple, linear component. And compare it to: The first one creates a div with 3 children with the type of the last one depending on the condition. The second one creates a div with 4 children (and a warning in the dev console). Both have 4 lines between the <div> with the same content except for two attributes on two elements and are indented the same by convention of the framework. They look nearly identical when quickly parsing over them but results are very different.reply