ractivejs / ractive

Next-generation DOM manipulation
http://ractive.js.org
MIT License
5.94k stars 396 forks source link

Templates are not HTML valid #185

Closed binarykitchen closed 11 years ago

binarykitchen commented 11 years ago

... of course because of the Mustache-like syntax. A small disadvantage compared to AngularJS. I will want to run them through a validator to check syntax.

For example this one http://dnajs.org/ would maintain html validity.

(Again, just raising another question ...)

Rich-Harris commented 11 years ago

Yeah, that's right. To be fair Angular templates aren't valid HTML either, because of all the ng-click attributes and so forth (yes, you can use data- attributes instead but no-one does!). The difference is that the DOM rendered by Ractive is valid, unlike Angular's invalid, stuffed-full-of-exposed-implementation-cruft DOM ;-)

Right now Ractive is quite tightly coupled to its implementation of Mustache. I haven't properly researched this, but I'm not sure how many other templating languages would work as well as Mustache does - it has certain properties (e.g. the fact that its structure is essentially logic-free) that dovetail neatly with how Ractive works. For that reason it's unlikely that the template language will change in the near future, if at all.

In theory, if you give Ractive any HTML that wouldn't be valid without the Mustache stuff, the parser will throw an error. The parser errors are a bit cryptic at the moment, but as a general rule if Ractive accepts it the syntax is fine.

There's another issue - things like on-click='select' and intro='fade' look like attributes but actually aren't (they're instructions to Ractive). Ractive knows that they're not, but an HTML validator wouldn't. So even without Mustache, many templates wouldn't be valid. So in common with other templating engines, validity has to be sacrificed on the altar of usability!

binarykitchen commented 11 years ago

Been working with Angular before and always amended data- there. So I were able to validate the markup to a certain degree. I cannot emphasize enough how important it is to be able to validate the markup. I'll come to that further down

Scarified for the sake of usability? Maybe but I think this is not an excuse. There are always solutions.

So, here some more questions:

So, about valid HTML, why do we have W3C standards at all? Browsers are forgiving but this does not mean, we can abuse them without worries. Too many break them. Code validation does help your scripts run better. Think about one o the cardinal rules... have you ever had two elements with the same ID on a page and tried to document.getElementById() in your js?

When I make mistakes in CSS, JS or HTML whatever, the W3C validator sometimes helps me spotting these. But I cannot do that anymore when the markup is already full with errors that come from web frameworks.

codler commented 11 years ago

Put your template in <script id='myTemplate' type='text/ractive'> and you wont have any validation problem.

binarykitchen commented 11 years ago

Mmmhh, I don't know.

This does not solve the problem: script tags just filter out some markup but does not validate them either. In other words, invalid markup gets ignored which can be worse in some cases.

ghost commented 11 years ago

Just because the templates are not valid HTML doesn't mean that the output they produce isn't valid HTML (which is all Google and the browser cares about). I'm not sure how well the W3C validator works on dynamic Javascript powered pages anyway? (assumedly it just inspects the DOM as it is in the initial page load?). You could probably validate the output of individual templates if you wanted to.

I'd really prefer Ractive to stick with it's current templating approach rather than add data- attributes.

Rich-Harris commented 11 years ago

You raise some good points, I'll address them in turn

why can't we use data- too here?

This could be added, but it wouldn't really make any difference except in a small subset of cases - I'll explain why momentarily

is there a plan in the foreseeable future to introduce an option to switch the template language from Mustache

No - the possibility is there at the back of my mind but I don't see a way of making Ractive work with arbitrary templating engines without a huge amount of reengineering. It's not a case of just swapping out Mustache with a different engine, because Ractive (being fundamentally different to other templating engines, in that it's a string -> DOM engine rather than string -> string) has its own Mustache parser. Any other language would require its own Ractive-specific implementation, unless the entire approach was completely rethought. As far as I'm aware only React works with arbitrary string generation (Meteor did, but I believe they're moving away from that approach because it comes with too many WTFs).

Did you know that Google uses the HMTL validity in its page ranking algorithm?

Yes. Google will interpret the HTML that is initially sent down the wire, and shoddy HTML will get penalized. In some cases, it will execute JavaScript and take a second look at the page, to deal with apps that are mainly rendered on the client.

As far as the first bit goes, there are a few possible scenarios:

Now the second bit, where Ractive actually renders the DOM. At this point we're not dealing with HTML any more, so there's no such concept as 'invalid markup' - Ractive constructs the DOM programmatically. In effect, we've bypassed the browser's HTML parser. This is what I meant above when I said that adding data- attributes wouldn't make any difference - the browser never actually sees those attributes, because intro and outro and on-* never get 'rendered'. True, prepending them with data- would mean templates validated if the Mustache structure didn't already invalidate them, but I'm not convinced that's an important goal.

did you know that browsers render faster when they deal with valid markup?

Yes - again, this isn't relevant with Ractive because we're not presenting it with markup (except in a few cases where we can safely transport part of a template as HTML, in which case we use innerHTML).

I think there's a larger issue here - we're moving away from a world where browsers are presented with static HTML, and towards one in which templating languages play a large role, which means the traditional role of validators is becoming outmoded. It might make more sense for frameworks and libraries like Ractive to do their own form of validation - there are arguably some things that Ractive could warn on (the duplicate id attributes is a good example). An analogy would be SASS complaining that my .scss file contains errors, rather than sending invalid CSS to the browser.

Phew - and after all that, I see that @micmcg said the same thing with about 5% of the words!

OliverBreuer commented 11 years ago

On 25.09.2013 10:59, Rich Harris wrote:

There's another issue - things like |on-click='select'| and |intro='fade'| look like attributes but actually aren't (they're instructions to Ractive). Ractive knows that they're not, but an HTML validator wouldn't. So even without Mustache, many templates wouldn't be valid. So in common with other templating engines, validity has to be sacrificed on the altar of usability!

Regarding usability I personally prefer a prefix for any framework related attributes. With attributes like on-click and intro I cannot easily see if the attribute is kept when rendering or if they are interpreted and stripped by Ractive. It makes the code hard to read, because to be able to understand the code you have to know all defined attributes. A long prefix like data- is probably bad, too. But a short one like ng- would be nice. I would be happy if a short prefix could be optionally used.

Rich-Harris commented 11 years ago

We could maybe follow Angular's lead and allow something like rv-click and so forth. Or rv-onclick, to differentiate it from rv-intro and rv-outro and any other attribute-like instructions that get added in future.

Balanced against this is the desire to have one recommended way of doing things, and most developers' (in my experience, at least) to keep syntax as lightweight and clean-looking as possible.

Thoughts?

binarykitchen commented 11 years ago

Wow, @Rich-Harris, you explained this very well. Your words explain it all:

"Ractive constructs the DOM programmatically. In effect, we've bypassed the browser's HTML parser."

The idea of validating the dynamically generated HTML is a good idea for later, amen. Thanks Rich-Harris again for your time.

@Others Yeah, rv-* is a great idea! +1 (and belongs to a new thread)

codler commented 11 years ago

I like it to be lightweight and clean looking :)

Rich-Harris commented 11 years ago

@binarykitchen you're welcome! Thanks for the interesting questions