Very nice article from one of two authors of Google Closure. In short, almost all MVC frameworks are bad designed in term of user experience. Btw, when I developed Este MVC, I decided to implement “Pending navigations” from ground. Now, I am working on rest of tips from article. Read it. Remember it. Use it :)
medium.com/joys-of-javascript/4353246f4480
It can be confusing, but it is really simple.
Soy and object with string properties. This is common scenario for este.Model.
Soy and object without string properties.
I don’t like writing blog posts just to make blogging noise. Este has changed a lot in last several months, if you follow https://twitter.com/estejs, you know.
We fixed coffee2closure fixer, added Bower and GruntJS, whole dev stack was refined.
I definitely have plans to make website, tutorials, etc. but, that’s crap is not so important as the code, unit tests, and demos.
So, stay tuned.
https://developers.google.com/experts/members/
I’m honored. I didn’t ask anyone. I just suddenly got a mail from Filip Hráček, and now I am packing my stuff and looking forward to devirtualization many of my friends from Moutain View. People are the most interesting thing on this planet :)
[Updated: new Este has a new cmd options, take a look at github.com/steida/este]
Google Closure has a powerful and very smart approach for string localizations. Unfortunately, they didn’t open source all their tools yet. Fortunately, I decided to add missing components and as result, we can enjoy awesome, the state of art ofc :), localization tools. It’s simple.
How to define message in code
###*
@desc Text shown in alert after click.
###
app.MSG_THANKYOU = goog.getMsg ‘Thank you!’
@desc attribute is required and compiler will check its existence. Why? It helps to translate the same messages in different contexts.
How to define message in template
/**
* @param action
*/
{template .callToAction}
{msg desc=”text in some div calling to action”}
{$action} on me {/msg}
{/template}
Same principle just with a different syntax. msg tag generates goog.getMsg function.
goog.getMsg placeholders
var MSG_NAME = goog.getMsg(‘Hello {$placeholder}’, {‘placeholder’: ‘world’});
How to generate dictionaries from source code
node run app -em aj fr cs
How to insert messages into compiled code
This command will generate app_fr.js script with goog.LOCALE = ‘fr’.
Hope this helps.
I have to set up public available build, but in the meantime, checkout and try TodoMVC done in Este way.
Once upon a time, John Resig made an experiment with client side micro templating. He discovered that embedding scripts in HTML page without known content-type prevents HTML parsing. He simply made HTML island in page.
Even though he described this technique as “quick-and-dirty technique for cases where I just need a little template or two on the page”, many developers blindly copied his approach as example practise for their framework. Here, here, and here.
What’s wrong with that?
It’s slow. Script element has to be retrieved from DOM, then its string .innerHTML content parsed, then template precompiled into reusable function. Take a look at Resig experiment to see it in work.
It’s bad for maintenance. Imagine your app will use 36 different templates. Where to store them? In main.html page? All of them? Unmaintainable. Some other frameworks chose even worse solution, to load template dynamically. OMG so many senseless requests.
Este.js approach
Templates are compiled immediately in the same manner as CoffeeScript or Stylus. For example, template dommerge.soy is compiled into precompiled function https://gist.github.com/3807295. Note that template has a namespace, and how that namespace can be required from code using it. Finally, code and templates are joined into one compiled JavaScript output. It’s good for overal compression, but it’s good also for dead code removing. Which such dependency system, we are able to disable some app feature even with their templates.
clientId is model ID generated on the client, before server return real ID. ClientId is used for rendering, routing, and everywhere where we need to mark something, without knowing real server provided ID. ClientId is not unique nor persistent.
This concept is used in http://backbonejs.org or YUI model for example. There is also another concept, generating GUID’s on client. Read what Jeremy Ashkenas wrote about it. Also, we still need server side IDs.
clientId issues
ClientId is not unique nor persistent. Imagine we want to develop offline first application, we need unique enough IDs to create url’s and to store model into browser localStorage. Later IDs updating is one way ticket to hell. And classic GUID is too long (product/00DE602B-F3D5-4816-A198-8425C91F7F1D).
Este.js approach
Similar to Backbone, except Este.js generates shorter IDs, using alphabet instead of numbers.
Backbone - c1, c2, c3
Este.js - :a, :b, :c
For client side localStorage persistence, este.storage.Local will create ID on model, if needed. It uses a combination of random and current timestamp, and then encodes the string in base-36 to make it shorter. It looks like this: sn1s7vb4gcic.
Human readable and unique enough, also fine for URL. Remember, we can always change app state URL projection later.
I don’t like that. Why? Because it’s smells like hard coded service locators. Tiny code snippets lost in elements attributes.. Compile check? No. Easy refactoring? No. Only spaghetti. Bon appetite!
Knockout
<section id=”main” data-bind=”visible: todos().length”>
AngularJS
<form ng-submit=”addTodo()”