I'm trying to make a modern site that loads data using ajax, renders it in a template and uses jQuery and pushstate to display it, plus server-side rendering so that initial page loads are fast and spiders can crawl as intended. Of course, I read the article about linkedin using dust.js to achieve this.
Now, dust.js claims the following advantages:
Composable: Designers should be able to break presentation markup into manageable components and combine these components at runtime. It should not be necessary to statically link templates or manually assemble 'layouts' inside application code.
Format agnostic: While HTML generation and DOM manipulation are useful in specific instances, a general-purpose template system should not be tied to a particular output format.
So it sounds great, but how do I actually achieve what I want? I've made templates that render a complete page just fine on the server, but they use blocks and inline partials - which means the internal bits can't be rendered at all without the wrapper present (it just returns an error that says it can't find the wrapper template). I don't see how composing inside application code (as opposed to selling point #1 above) can be avoided on the client.
I don't understand what #2 above even means. I guess it means that you get the output as a string and can do whatever you want with it?
The documentation is about as clear as mud.
So what do I do? Is there a better option than dust.js these days? Do I write templates so that they must be composed in application code? If so, by what mechanism do I compose them in application code?
Ok, since there has been trouble understanding my question (which is itself understandable), I just threw together this (untested) example showing the problem:
Wrapper template:
<html>
<head><title>{+title/}</title>
{+styles/}
</head>
<body>
header header header
<div id="pagecontent">{+content/}</div>
footer footer footer
<script src="jquery"></script>
<script src="dust"></script>
<script src="see 'Client side script' below"></script>
</body>
</html>
'time' template:
{>wrap/}
{<title}Time in millis{/title}
{<styles}
<style>
body {
background-color: {bgcolor};
}
</style>
{/styles}
{<content}
The time: {time}<br />
<a href="{link}">Switch format</a>
{/content}
Server side code:
app.get('/millis',function(req,res) {
res.render('time',{millis:new Date().getTime(),link:'/time',bgcolor:'lightgreen'});
}
app.get('/time',function(req,res) {
res.render('time',{millis:new Date().toString(),link:'/millis',bgcolor:'lightpink'});
}
So, the server will render the page fine, but what about the client? Read on.
Client side script:
//load the 'time' template into dust somewhere up here
$(function(){
$('a').click(function(e){
var newcontent;
switch($(this).attr('href')) {
case '/time':
//FAILS: can't find the wrapper. We need logic to get the title and styles from the template and fill it in in-place in the DOM
newcontent = dust.render('time',{millis:new Date().toString(),link:'/millis',bgcolor:'lightpink'});
case '/millis':
//FAILS: can't find the wrapper. We need logic to get the title and styles from the template and fill it in in-place in the DOM
newcontent = dust.render('time',{millis:new Date().getTime(),link:'/time',bgcolor:'lightgreen'});
default: return;
}
e.preventDefault();
$('#pagecontent').fadeOut(1000,function(){
//use pushstate and stuff here
$(this).html(newcontent);
$(this.fadeIn(1000);
});
});
});