akdubya / dustjs

Asynchronous templates for the browser and node.js
http://akdubya.github.com/dustjs/
MIT License
1.44k stars 124 forks source link

Unflushed Chunks #21

Open kmdavis opened 13 years ago

kmdavis commented 13 years ago

Sometimes dust gets stuck in an asynchronous block at the end of a template. We have our own subtemplate/partial include system, and sometimes, for some templates, after ending a stub, it doesn't get flushed.

I fixed the issue locally like this, but it's kinda scary: (works for our use cases though)

Stub.prototype.flush = function() {
  var chunk = this.head;

  while (chunk) {
    if (chunk.flushable) {
      this.out += chunk.data;
    } else if (chunk.error) {
      this.callback(chunk.error);
      this.flush = function() {};
      return;
    } else {
      // Sometimes, dust get's stuck here, at the end of a template, and something thinks there's more to do
      // chunk.next is undefined
      if (!chunk.next && "" === chunk.data) {
        break;
      }
      return;
    }
    chunk = chunk.next;
    this.head = chunk;
  }
  this.callback(null, this.out);
}

Also, for reference, here's our custom include helper:

dust.helpers.include = function (chunk, context, bodies, params) {
  return chunk.map(function(chunk) {
    var ctx = (params && params.context) || context.get("context") || context.current();
    ctx.currentDustIndex = context.stack.index;
    ctx.currentDustLength = context.stack.of;
    Gilt.Template.render((params && params.name) || context.get("name"), ctx, function (html) {
      chunk.end(html);
    }, {
      engine:  (params && params.engine)  || context.get("engine") || "dust",
      version: (params && params.version) || context.get("version")
    });
  });
};

And an example of it in use: {@include name=\"cart\" version=\"countdown\" context=sku/}

kmdavis commented 13 years ago

Actually, this hack doesn't work for our usage. It produces output, but the output isn't in Quite the right order

kmdavis commented 13 years ago

Ok... fixed it locally. Reverted that hack above. In my usage, I had an if statement wrapped around the include. By moving the if statement into the partial, it works. But it would be nice not to have to do so