1

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:

  1. 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.

  2. 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);
        });
    });
});
4

1 回答 1

0

我想知道同样的事情并遇到了这个。你可能也看过这个,但我把它留在这里以防它帮助其他人。

http://spalatnik.com/blog/?p=54

我还没有实现这一点,所以我下面的推论是基于上面的文章和一些(希望)有根据的假设。如果以下内容不正确,我当然想继续讨论,因为我也在学习。

我怀疑你会有两种类型的包装模板。一个是您在上面提供的包装模板(用于服务器端渲染)。第二个包装模板将完全不同(如下所示)。在以下示例中,我从上面的博客中逐字复制。我假设你所有编译的 DustJS 模板都在下面的文件dust-full-0.3.0-min.js 中。

<html>
<head>
<script src="dust-full-0.3.0.min.js"></script>
<script type="text/javascript">
//example showing client-side compiling and rendering
var compiled = dust.compile("Hello {name}!", "index");
dust.loadSource(compiled);

dust.render("index", {name: "David"}, function(err, out) {
  if(err != null)
    alert("Error loading page");
  //assume we have jquery
  $("#pageContainer").html(out);
});
</script>
</head>

<body>
<div id="pageContainer"></div>
</body>
</html>

我怀疑在您的 Express 服务器中,您会检查用户代理并决定渲染哪个模板。如果它是机器人用户代理,请在您的示例中使用服务器端生成。否则,请使用上面的客户端模板。

于 2014-01-28T20:58:06.210 回答