google / dart-tagtree

A React-like UI framework in Dart
Apache License 2.0
78 stars 14 forks source link

Better HTML templates #5

Open skybrian opened 10 years ago

skybrian commented 10 years ago

In TagTree, you implement HTML templates using render functions. These functions construct ElementTags by calling methods on HtmlTagSet.

This is about as readable as I could make it using pure Dart, but the results are only so-so. Render functions would be easier to read if you could use real HTML tags in Dart, similar to React's JSX.

Perhaps a Dart transformer could do this, but it would require implementing and extending a Dart language scanner and parser. Dart doesn't seem to have a public API for this.

sethladd commented 10 years ago

What about triple quote strings?

skybrian commented 10 years ago

Perhaps. It might be something like this:

return $.template('"""

{{.something}}
""", {"something": 123});

But the parsing would have to be done at runtime in the browser (though it could be done once and cached) and you have to pass the template variables in, resulting in repetition. JSX lets you embed expressions that access any variables in scope.

skybrian commented 10 years ago

On second thought, triple-quoted strings would work well with existing tools (such as the Dart editor) since they'd ignore the language extension. But I still think they should be expanded at compile time by a transformer.

sethladd commented 10 years ago

I'm not an expert, but are you talking about using templates just for string interpolation, or also looping and conditions?

skybrian commented 10 years ago

I'd rather have looping and conditionals in Dart. But it's not really string interpolation either because the output is a node or a tree of nodes, not a string. TagTree attributes can be arbitrary Dart values.

In JSX you can use arbitrary JavaScript in your template function. I like this because it avoids inventing what Gilad Bracha calls a "shadow language" [1] just for templates. Currently TagTree supports this since it doesn't have a template language, just methods for constructing nodes. Therefore it supports full refactoring in the Dart Editor, though it's not that convenient in practice since the Dart formatter messes up TagTree expressions.

Of course it's only one design tradeoff. If you're willing to use a shadow language then the AngularDart / Polymer approach of putting HTML template in HTML files makes a lot of sense.

[1] http://gbracha.blogspot.com/2014/09/a-domain-of-shadows.html

sethladd commented 10 years ago

I don't want a shadow language :) I'm pro loops and conditions in Dart code.

Sounds like we do need a transformer, but I'd like to run the transformer only when building for production. I want simple edit/refresh when doing development. I'm ok with slower runtime performance during development (perhaps via mirrors?) as long as I don't have to invoke a transformer on every refresh.

skybrian commented 10 years ago

The problem is that I'm not sure if we can improve much on the existing syntax while remaining mostly in Dart. Suppose we want to construct a node. Currently in TagTree it looks like this :

var myConfig = ...; return new MyApp({config: myConfig});

I could see using a template to do this, but it hardly seems worth it:

var myConfig = ...; return $("");

(It can't be string interpolation because we don't want to serialize myConfig and then deserialize it again.)

Ideally Dart would support XML-like syntax natively as syntactic sugar for constructor calls:

var myConfig = ...; return ;

But even with a transformer, it breaks all the other tools. That's the problem with language changes.

oskbor commented 9 years ago

Some XML like syntax like with JSX would be cool and really helpful for dart I think. Would it be possible to implement it in a way so that different libraries could be supported? Like tagtree, dart:html , tiles, vdom or other dom/ virtual dom libraries.

//dart:html
HtmlElement myElem  =<?  <div> <span> hello </span> </div> ?>

//tagtree
 Tag myTag = <? <myCustomThing> <div> yadda yadda </div> </myCustomThing> ?>

Im guessing this would have to be a new language feature to be really useful