- (Size) 16 KiB compressed is understatement, because RL does not do strong minification. In practise if we load it through RL the size is going to be a bit higher because of that.
- (Fork?) It looks like you are planning to do fairly extensive changes as opposed to just using KnockOut.js directly. It is unclear to me how this will be maintained, what changes need to be made to KnockOut.js itself and what is just our own additions.
- (Complexity) KnockOut.js syntax looks very complex. I understand that we do not want to use string-based templating systems, but that doesn't mean we need to choose a one that embeds a full programming language inside it. (In any case I will have a lot of porting work to do)
- (???) I do not understand section MediaWiki messages in JSON IR at all. It seems to assume a certain goal that the implementors want to achieve which is not written down.
- (Integration) I disagree with the statement Knockout.JS is immediately ready to be used as a reactive templating library on the client. I've used Mustache on my own, but without RL integration it is quite painful. In this proposal the actual MediaWiki RL integration seems to be collapsed into one bullet: template delivery via ResourceLoader. I would like to see more content how the actual integration will look. Will there be a key 'templates' in RL modules? What are the naming conventions and file extension for templates? How about i18n integration (see my other thread)? Compare with https://gerrit.wikimedia.org/r/111250 . And how about client side? How will I add a template on the page after it has been loaded by RL?
- (Integration2) And going even further (out of scope for this RFC probably), templates are going to need data, for example via the WebAPI. There should be some way that RL modules can request data delivered from API modules without extra round-trip. It might also be possible that we want to do it in an other way, to create data providers that are easy to use in PHP but also provide automatic RL or WebAPI wrapping to accomplish the data delivery to client side.
Talk:Requests for comment/HTML templating library/Knockoff - Tassembly
Quick note about including templates *dynamically* and having them start updating right away. Here's an example of a custom binding to do that:
https://github.com/wikimedia/limn/blob/master/src/util/knockout/subview-binding.co
This post was posted by Milimetric (WMF), but signed as DAndreescu.
Some replies:
- Possibly, although I'd imagine it to be possible to check in a pre-minified version if we want.
- For client-side rendering the main task is hooking up messages etc. We can also syntactically restrict what is allowed in expressions (for sanity and compatibility with server-side templates), but that is really optional. Stock KnockoutJS can be used as-is (and is already used by analytics), although I agree that RL integration is very desirable for MW.
- Basically see 2), either by convention or by enforcing it in the KnockoutJS expression compiler (a simple regexp).
- I think we touched on this in the discussion. We can basically compile messages to the JSON IR and then execute it using the same runtime.
- KnockoutJS templates can be dynamically added in the model (as a reference to a DOM node) or as an id in the page DOM. The details of the RL integration are not yet set in stone. We will definitely look closely at what has been done in that area so far (thanks for the links!) and will solicit input.
- We actually thought about data sources a bit, with the option to pull data asynchronously vs. statically determining the data that is going to be needed at compile time and pre-loading it. The problem with statically determining data sources is that you need to be conservative about which branches are taken, so you might end up more data than actually needed. On the server we'll probably do this as an async / parallel pull similar to the way Parsoid works internally. On the client the expense depends on whether the content is pre-rendered (and only needs to be updated later) or not.
Why tags has to be closed explicitly in JSON structures? Nested arrays / objects itself are self-closing:
["<div",["attr",{"id":"id"}],
["foreach",{
"data":"links",
"tpl":["<a",["attr",{"href":"url"}],">",["text","description"]]
}],
])
"foreach" is not closed such way, wouldn't that be more consistent? QuestPC (talk) 19:26, 26 March 2014 (UTC)
TAssembly is designed for easy and efficient processing. Runs of static template text are just encoded as strings, which are emitted verbatim by the runtime. Those runs often contain many tags, which is much more efficient than representing each tag as a JSON (or XML/HTML DOM) structure.
I just read about knockout.js. Sounds interesting, but I just did not really like how nested templates are implemented. They are not functional but like usual iterators: http://stackoverflow.com/questions/7313554/nested-templates-with-knockoutjs-and-mvc-3-0?rq=1 Nesting is lost in template definition, it would be better if actual nesting was preserved.
<script type="text/html" id="TopTemplate"> <li > <p>${name}</p> <ul data-bind=" template: {name: 'NestedTemplate' , foreach: parents } " style="list-style-type:circle;margin-left:15px"> <script type="text/html" id="NestedTemplate"> <li> <p>${name}</p> <ul data-bind=" template: {name: 'parentTemplate' , foreach: children } " style="list-style-type:circle;margin-left:15px"> </ul> </li> </script> </ul> </li> </script>
However that's better than plain string output, anyway. QuestPC (talk) 16:51, 31 March 2014 (UTC)
I read more about knockout.js. Then I liked it and started to use in my non-MediaWiki projects. It's quite nice library indeed. The only thing I miss is more complex "if:" binding than just a null / boolean / zero comparsion. It would be great to have a PHP port indeed - either for MediaWiki and standalone. I guess the whole skinning could be ported into knockout syntax. Thank you for pointing to this library.
- (Syntax) I was secretly hoping for data-i18n kind of syntax used by jquery.i18n, but I can live with this new syntax as well. Have to say though, that is looks extremely verbose, meaning that we should figure out a sensible convention for splitting tag openings into multiple lines.
- (Variables) It looks like this syntax supports passing variables to messages. Does it accept array of values like current message functions? Or perhaps an object with keys as variable names as well (it divers from our current practice, but named variables are not a bad thing).
- (Message API) I'm not sure the current mw.message is a thing we want to integrate too tightly. Perhaps we can abstract the integration a bit so that it can be replaced. mw.message is MediaWiki specific and there are wishes to either create a standalone library based on it or replace it with another library. Having said that, using mw.message right now makes sense.
- (Message formats) Further thought is needed to figure out what we do with the different output formats of mw.message. Do we give the control to the user? Or do we automatically select suitable format based on the context?
- (RL) Are we able to preprocess the templates in such a way that we can see what messages are used in it, and load those automatically? The current thing of having to specify what messages to load is quite annoying. There are also messages used only in the JS, so perhaps this won't solve the problem entirely. Another option is that people might start splitting messages to different files per template, and then just load all messages defined in that file.
- (Live updates) It was not mentioned clearly in the proposal, but I assume we are able to update the strings into different language "live" as we can do with jquery.i18n.
- (Syntax): i18n can look like data-bind="i18n: messageName". The advantage of using a single attribute is performance and simplicity. Those attributes can be formatted across multiple lines.
- (Variables): The syntax trivially and generically supports passing both arrays and objects to messages, but we can be more selective about what we accept in the i18n binding.
- (Message API): At first sight it looks like we can define an interface that can remain unchanged even if we swap out mw.message against another backend later.
- (Message formats): Much of this would normally be handled by automatic escaping and compilation from the input format. The input formats of messages are properties of the messages themselves, so should not be specified by a user. The escaping needed depends on where in the DOM a message is used, which is handled by the templating system.
- (RL): It is fairly easy to extract a list of all messages that could possibly be used in a template if message names are not dynamically constructed from input data. Optimizing the bundles of messages could be done based on usage statistics, with the common messages all delivered in one bundle and additional messages loaded on demand. This is a longer-term optimization opportunity.
- (Live updates): With native knockoutjs this can be solved by making the translations observable. This allows dynamic updates of both data *and* messages, and re-rendering is handled transparently by KnockoutJS. If we use just quicktemplate, then one option is to simply re-render the template with new messages set in the model. Another could be to implement an i18n-specific pass that only re-expands i18n nodes, although the difficulty there would be getting the data scoping right.
This sounds great.