You are not logged in.
Pages: 1
I would like to play with mustache & mORMot. I started with a static HTML (teste.md) and then I'd
like to make it dynamic by adding server code to it.
<html>
<head>
<title>A Simple Mustache Demo</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>A Simple Mustache Demo</h1>
<h4>Product Info: {{name}}</h4>
<ul>
<li>Product: {{name}}</li>
<li>Colour: {{colour}}</li>
<li>Price: ${{price}}</li>
</ul>
</body>
</html>
When I type into address bar "http://127.0.0.1:8080/root/teste.md" this "hello world" sample
should output a HTML result something like:
<h1>A Simple Mustache Demo</h1>
<h4>Product Info: SuperWidget</h4><ul>
<li>Product: SuperWidget</li>
<li>Colour: Green</li>
<li>Price: $19.99</li>
</ul>
Is it possible? I'm using project 22 - JavaScript HTTPApi web server.
Offline
Why use the JavaScript version of the mustache renderer?
Our native SynMustache unit will perform much better.
See http://blog.synopse.info/post/2014/04/2 … phi-part-3
In this blog article, you have all input to process mustache templates easily.
Note that I would like to provide some MVC native support and sample code soon.
BTW, *.md files are MarkDown files, not mustache files.
Usually, mustache files have the same extension than the final content layout, e.g. .html or .txt.
I would certainly use Mustache to create the mORMot client wrappers for Java, C#, JavaScript/SMS or even Delphi mobile Indy-based clients...
So here the mustache template files would be... .pas!
Offline
But I'm hungry I need a long time to digest this information. This seems to be more powerful than nuclear weapons.
Offline
I just wrote a small sample program, for benchmarking Mustache libraries: native SynMustache vs mustache.js running on SpiderMonkey 24...
And the winner is SynMustache, which is 10 times faster, uses almost no memory during process, and handles inlined {{>partials}} natively (whereas we have to handle them manually with mustache.js)!
Who says that Garbage Collection and immutable strings in modern JITted runtimes are faster than "native" Delphi applications?
Are you still preferring the "NextGen" roadmap?
See http://blog.synopse.info/post/2014/05/0 … iderMonkey
Take a look at "SQLite3/Samples/23 - JavaScript Tests/TestMustache.dpr".
Offline
Such a nice work !!
Offline
You're one of the best Delphi advocate I've read in the last few years ! That's the kind of demonstration that give me the desire to continue working with Delphi, and could give me new ideas too, or ideas I would not have thought of developing with Delphi... What are Embarcadero doing ? We and they need more people like you !
Offline
You are simply the best . I like your comparison and explanation about what really matters, real application versus some "academic calculation" as is Mandelbrot computation...
"Uncertainty in science: There no doubt exist natural laws, but once this fine reason of ours was corrupted, it corrupted everything.", Blaise Pascal
Offline
How can I list firstly all names which isGood is true? Expected HTML result would be:
<h3>Languages</h3>
<p>Delphi</p>
<p>Java</p>
<p>dotNET</p>
<p>PHP</p>
<p>Ruby</p>
Template := StringToUTF8(
'<h3>Languages</h3>'+
'{{> person}}'+
'{{<person}}'+
'{{#users}}'+
' {{#isGood}}'+
' <p>{{name}}</p>'+
' {{/isGood}}'+
'{{/users}}'+
'{{#users}}'+
' {{^isGood}}'+
' <p>{{name}}</p>'+
' {{/isGood}}'+
'{{/users}}'+
'{{/person}}'
);
Context := StringToUTF8(
'{"users" : [{'+
' "name" : "DotNET",'+
' "isGood" : false'+
' }, {'+
' "name" : "Delphi",'+
' "isGood" : true'+
' }, {'+
' "name" : "PHP",'+
' "isGood" : false'+
' }, {'+
' "name" : "Java",'+
' "isGood" : true'+
' }, {'+
' "name" : "Ruby",'+
' "isGood" : false'+
' }'+
']}');
Last edited by warleyalex (2014-05-08 21:34:06)
Offline
Very nice results!
However, I heartily disagree on you benchmarking conclusions for several reasons
Perhaps it's my scientific training, but I believe that focused experiments & measurements always yield interesting fundamental insight.
And case in point, your benchmark is synthetic and focused, where Mandelbrot measures tight loops and simple floating point operators, your benchmarks measure loops, buffer writes and string lookups.
Also, Mustache js isn't really optimized for speed, but for size (hence all the Regular Expressions), and there are faster, Mustache-compatible JS libraries (like Handlebars f.i, which is said to be 2x faster than Mustache, but that in special cases can be 100 times faster).
The reason why optimizing for size makes sense, is that in a "real world" high-performance application, you shouldn't be processing the templates on the server-side in the first-place, that's why I think your benchmark is no more "real-world" than Mandelbrot. Though it likely provides more insight on your coding skills than on the Delphi compiler's own strength I'm afraid
Logic-less templates real strength comes in client-side processing, where they have numerous advantages:
- processing power linearly goes up with the number of clients, and thus is never an issue as long as it's fast enough for the slowest client
- server-side CPU requirements are limited to data-extraction & JSON generation
- templates are static, and thus can be cached on the client (zero bandwidth after 1st load) or served by geo-located CDN (practically unlimited bandwidth)
- server bandwidth requirements are reduced to just serving the data
- since the templates are logic-less, you don't leak any business know-how to client-side execution
- fundamentally different rendering of the same data from the same server is possible, without touching anything on the server, and with no risk of a faulty template/rendering affecting server performance
So where a server-side Mustache will result in ever-increasing load, especially bandwidth load which you're likely to run out well before you run out of CPU on a web-based application, especially if want to serve the whole world, a client-side Mustache will only be limited by the data extraction & bandwidth rates, ie. the speed at which you can extract, generate & send the data.
And when the data itself can be cached & shared (even for short durations), there is practically no limit to scale-ability.
Case in point, my current DWS WebServer experimentation involves serving datasets up to the megabyte range, with usage spikes of hundreds of simultaneous clients, the megabyte of data getting rendered to several megabytes of HTML (once you factor scaffolding & class tags for convenient CSS presentation + IDs for JS interactivity, html quickly balloons up). All this from a mere 10Mbit/s server, which if you do the maths, just wouldn't have the bandwidth (nor the latency, nor the CPU) to handle the load on its own.
The client-side tech is not Mustache, but the fundamentals of client-side rendering & geo-located caching are the same (in my case, it's Cloudflare that's takes the brunt of the load). During a time one link got popular, it averaged a week at 30000 pageviews per day, that's plenty of gigabytes of data, and even more gigabytes of rendered html if it had been done server-side, and way more than the server could have handled on its own.
Offline
Here I should agree with Eric, HTML rendering in modern web applications should be done on client side, and hard data manipulation and serving at server side.
At least this is what most applications do, retrieve the data (binary or json) from a server (most likely not sql but rest), and visualize it depending on its kind (native win, native mac, browser web site, browser app).
We have great and powerful framework at server side, no doubt.
But following tendencies and client's requests, it is more common to build client applications not using delphi native apps, nor C#, but thin js+html+css apps, enabled on all devices, backed up by powerful data server.
What will be in great benefit for the community, in my opinion, is a javascript client framework and/or library, easy interacting with mORMot server.
There a build-in templating will be at great benefit, but it is little peace of what such a framework should be.
Offline
@Eric & @Chapa
Nice having some feedback!
My blog post was indeed a trolling point of view - so I'm happy there are some reactions.
it likely provides more insight on your coding skills than on the Delphi compiler's own strength I'm afraid
... the Delphi compiler is far from perfect, but what I like so much is the memory/execution model of Delphi, and its abilities to mix high-level structures (like dynamic arrays or our TDocVariant with late-binding) and low-level structures for the core (like pointers or manual memory handling).
Every day, I consider switching to FPC... which does make sense for server side, doesn't it?
About modern web techniques, I totally agree with you: client side templates with AJAX requests and static content served by Cloudflare is the path to go.
But Mustache was designed to work on BOTH client side and server side, e.g. for the great http://www.meteor.com framework (using Handlebar enhancements of Mustache - I would follow this path also).
Logic-less templates have other advantages, like 100% uncoupling logic and presentation (whereas PHP, Razor or DWS do not).
AJAX requests represent only a small portion of web pages - and Mustache was designed for real web site (used by Twitter or by Google, in its parent ctemplate).
a javascript client framework and/or library, easy interacting with mORMot servers...
is what we want to do with Mustache + interface-based services.
With the possibility to compute the static content on either client or server side.
If you want to know what I have in my, go visit http://www.meteor.com and check out!
There are some missing part yet, like the event mechanism we wanted to implement in mORMot.
I'm currently investigating also about http://goratchet.com/ and http://getbootstrap.com/ for application theming, since I'm definitively no CSS expert!
Offline
I'm currently investigating also about http://goratchet.com/ and http://getbootstrap.com/ for application theming, since I'm definitively no CSS expert!
Hi Arnaud, I'm no CSS expert too, and I found that the HTML inspector in Firebug or DevTools to be indispensable for CSS thing, and that why I am developing LIVEditor (http://liveditor.com) which has a similar 'css inspector and locatior' included, just in case you find it may help, contact me and I'll be pleased to send you a free license
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Hi Arnaud, I'm no CSS expert too, and I found that the HTML inspector in Firebug or DevTools to be indispensable for CSS thing, and that why I am developing LIVEditor (http://liveditor.com) which has a similar 'css inspector and locatior' included, just in case you find it may help, contact me and I'll be pleased to send you a free license
Amazing!
I probably be interested by such a tool, and your technical feedback, soon!
Offline
This mustache is fucking cool. I created a mini pizza order menu using mORMot with mustache. I have the list of pizzas in a menu, when user, for example, select/order a pizza and click <Buy this> another template is rendered.
Of course, I'm using JS (the onclick attribute on my anchor tag). However, I've been thinking it would be really nice to have some basic mORMot controls instead of regular html controls: a server-side control, like in ASP.
<a href="#" runat="server" onServerClick="MyFuncion_Click" />
My opinion is that server-side rendering will almost always be faster than client side rendering.
Offline
The way ASP works has proved to be a mess due to it mix logics in the html markups, and that approach have been abandoned nowadays.
What makes the Mustache template engine appearing, is that, it's **logic-less**, the philosophy is that, no program logics in the template markups.
In your case, you can just use a js function, to handle the click event, and in that js function talk to the mormot server.
I think we should stick with standard and proven technologies.
This mustache is fucking cool. I created a mini pizza order menu using mORMot with mustache. I have the list of pizzas in a menu, when user, for example, select/order a pizza and click <Buy this> another template is rendered.
Of course, I'm using JS (the onclick attribute on my anchor tag). However, I've been thinking it would be really nice to have some basic mORMot controls instead of regular html controls: a server-side control, like in ASP.<a href="#" runat="server" onServerClick="MyFuncion_Click" />
My opinion is that server-side rendering will almost always be faster than client side rendering.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
I'm currently investigating several ways of doing simple web apps.
What I want to do is implement the MVC pattern with interface-based services.
There are several feature request tickets about this.
I would like to have the same exact Controller and Model code work:
- either as a Delphi client (with regular VCL forms for the view);
- or as a web application (with Mustache templates for the view).
Since even the VCL forms will be void of any logic, we may even try to auto-generate the web views from the VCL forms themselves, for simple apps...
Offline
Arnaud, Python's Flask framework is very elegant, IMHO: http://flask.pocoo.org/
I'm currently investigating several ways of doing simple web apps.
What I want to do is implement the MVC pattern with interface-based services.
There are several feature request tickets about this.I would like to have the same exact Controller and Model code work:
- either as a Delphi client (with regular VCL forms for the view);
- or as a web application (with Mustache templates for the view).Since even the VCL forms will be void of any logic, we may even try to auto-generate the web views from the VCL forms themselves, for simple apps...
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
@Eric & @Chapa
Logic-less templates have other advantages, like 100% uncoupling logic and presentation (whereas PHP, Razor or DWS do not).
They allow coupling, but don't dictate it. DWS has server-side compilation and strong-typing, so it's not like PHP where you can never now exactly what access what and how or when.
A downside of logic-less data-driven templates is that they're runtime-evaluated, with no strong typing, so they require more effort to maintain to maintain, and are error-prone (a weakness shared by untyped languages like PHP).
AJAX requests represent only a small portion of web pages - and Mustache was designed for real web site (used by Twitter or by Google, in its parent ctemplate).
I disagree, the XML portion of AJAX is pretty much dead, but the asynchronous, javascript-driven aspects have become ubiquitous.
Pretty much all of google and twitter webpages are JavaScript applications, which load not just the data asynchronously, but the presentation and the code itself, and arguably google "webpages" are architectured like traditional fat clients, with dynamic libraries, data access drivers, UI drivers & APIs, etc. they just happen to run in a web browser.
If you look at trends for gmail, charts, maps, google+, analytics, adsense, drive etc. they're all ever more heavy on the client-side logic, and they're all relying on javascript-driven asynchronous loading (many even have loading progress bar or pacifiers, which I don't consider a progress btw)
While mustache and logic-less templates was interesting as a reaction to PHP (and JSP), I'm not convinced it still is very relevant: you can built simple stuff easily with mustache, but you can't build modern web UIs with it, not without throwing a lot of JS or going through extra hoops. Popular template engines these days seem to all have logic.
Offline
While mustache and logic-less templates was interesting as a reaction to PHP (and JSP), I'm not convinced it still is very relevant: you can built simple stuff easily with mustache, but you can't build modern web UIs with it, not without throwing a lot of JS or going through extra hoops. Popular template engines these days seem to all have logic.
You can build modern web UIs with something like Mustache, and use it on both client and server side.
This is what https://www.meteor.com does (with Spacebars, inspired by Handlebars, which was inspired by Mustache).
As you wrote, just write (a lot of) JavaScript, in a MVC model (in Meteor, the Controller glue is implemented by some shared per-session variables, synchronized on both client and server sides).
But IMHO modern stateful web does not come without problems.
See https://www.discovermeteor.com/blog/sca … ltime-apps
For instance, the server has to maintain a list of the data state of each of its clients!
I still believe in the stateless model - since "from state comes complexity" - http://en.wikipedia.org/wiki/Occam's_razor
And honestly, for most web apps, it is just enough to have a the more stateless approach possible.
We are over-tooling the web and its stateless HTTP protocol (with something like websockets), just as we are over-using the bandwidth of our mobile phone carriers (if direct streaming of TV events was using broadcasting instead of regular HTTP, it may save a lot of bandwidth - even with 4G).
Is it worth it?
The whole Google page does a lot of requests - it even pre-download any future potential search pages!
So much power wasted for user experience!
http://ournewclimate.blogspot.fr/2013/0 … earch.html states that we should not abuse of searches on our side... but Google itself is preparing our potential searches in its servers!
As you say, I believe much more in the DWS + SMS pair, which would add the same exact language on both Client and Server side, but with strong typing.
Is it on track?
It may be a wonderful alternative to meteor, with several models (I tend to say that the meteor stateful/realtime model is too restrictive).
But if it is strong typing that you need, you could use https://github.com/orefalo/meteor-typescript-compiler ...
Offline
How to list firstly all names which isGood is true? This works for me. Expected HTML result was:
<h3>Languages</h3>
<p>Delphi</p>
<p>Java</p>
<p>dotNET</p>
<p>PHP</p>
<p>Ruby</p>
Template := StringToUTF8(
'<h3>Languages</h3>'+
'{{> person}}'+
'{{<person}}'+
'{{#users}}'+
' {{#isGood}}'+
' <p>{{name}}</p>'+
' {{/isGood}}'+
'{{/users}}'+
'{{#users}}'+
' {{^isGood}}'+
' <p>{{name}}</p>'+
' {{/isGood}}'+
'{{/users}}'+
'{{/person}}'
);
Context := StringToUTF8(
'{"users" : [{'+
' "name" : "DotNET",'+
' "isGood" : false'+
' }, {'+
' "name" : "Delphi",'+
' "isGood" : true'+
' }, {'+
' "name" : "PHP",'+
' "isGood" : false'+
' }, {'+
' "name" : "Java",'+
' "isGood" : true'+
' }, {'+
' "name" : "Ruby",'+
' "isGood" : false'+
' }'+
']}');
Thank you.
Offline
Yes, this sounds just like the way to do it.
I do not see any other simple way to do it.
Of course, defining a {{<person}} partial here may sound a bit overkill/unless you reuse it in the main template.
BTW, I've just added some methods to ease integration of Mustache template rendering with the ORM.
See http://synopse.info/fossil/info/a35d8737d5
To avoid any unneeded temporary conversion, you can use the TSQLRest.RetrieveDocVariantArray() method, and provide its TDocVariant result as the data context of TSynMustache.Render().
For instance, you may now write:
var template: TSynMustache;
html: RawUTF8;
...
template := TSynMustache.Parse(
'<ul>{{#items}}<li>{{Name}} was born on {{BirthDate}}</li>{{/items}}</ul>');
html := template.Render(
aClient.RetrieveDocVariantArray(TSQLBaby,'items','Name,BirthDate'));
// now html will contain a ready-to-be-displayed unordered list
Of course, this TSQLRest.RetrieveDocVariantArray() method accepts an optional WHERE clause, to be used according to your needs. You may even use paging, to split the list in smaller pieces.
In conjunction with method-based services, which can return directly HTML content to a HTTP client, you can easily create a high performance web server using mORMot, following the MVC pattern:
- Model will be the ORM and its TSQLModel / TSQLRecord definitions;
- View will be Mustache templates (which may be stored as separated files or within the database);
- Controller will be implemented in method-based services.
In the future, this MVC design will probably be enhanced, and benefit from interface-based services to write:
- Some part of the Model (i.e. the business logic);
- Some part of the Controller (i.e. the application logic).
Both Model and Controller logic, even if defined via interface, may be implemented in Delphi or even in JavaScript. Delphi code would gives strong typing, full integration to the framework, and the best performance possible. JavaScript code may be changed on the fly, and even stored as separated files.
Offline
Pages: 1