edge.js - Load compiled Dust.js templates in node.js -


i'm trying create function takes template name , able return rendered template string. using linkedin's version of dust. pre-compiling templates (using grunt-dustjs task) single file looks this:

(function(){dust.register("collections-nav",body_0);function body_0(chk,ctx){return chk.write("\t<div id=\"collection-loop\"><div class=\"section-title lines desktop-12\"><h2>shop collection</h2></div>").section(ctx.getpath(false, ["bigmutha","topnavigation"]),ctx,{"block":body_1},{}).write("</div>");}function body_1(chk,ctx){return chk.write("<div class=\"collection-index desktop-3 tablet-2 mobile-3 first\" data-alpha=\"").reference(ctx.get(["title"], false),ctx,"h").write("\">  <div class=\"collection-image\"><a href=\"").reference(ctx.get(["url"], false),ctx,"h").write("\" title=\"").reference(ctx.get(["title"], false),ctx,"h").write("\"><img src=\"//cdn.shopify.com/s/files/1/0352/5133/collections/d_cb_20140312_m_handpicked_grande.jpg?v=1394885208\" alt=\"").reference(ctx.get(["title"], false),ctx,"h").write("\" /></a>     </div><div class=\"collection-info\"><a href=\"/collections/mens-designer-clothing\" title=\"browse our ").reference(ctx.get(["title"], false),ctx,"h").write(" collection\"><h3>").reference(ctx.get(["title"], false),ctx,"h").write("</h3><p>16 items</p></a></div></div>");}return body_0;})()  (function(){dust.register("index",body_0);var blocks={"body":body_1};function body_0(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.partial("layouts/mainfull",ctx,{});}function body_1(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.write("<ul>").section(ctx.get(["topnavigation"], false),ctx,{"block":body_2},{}).write("</ul>").section(ctx.get(["products"], false),ctx,{"block":body_3},{});}function body_2(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.write("<li>").reference(ctx.get(["title"], false),ctx,"h").write("</li>");}function body_3(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.reference(ctx.get(["name"], false),ctx,"h");}return body_0;})()  (function(){dust.register("layouts.mainfull",body_0);function body_0(chk,ctx){return chk.write("<!doctype html><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>dust.js test template</title></head><body>").block(ctx.getblock("body"),ctx,{},{}).write("</body></html>");}return body_0;})() 

what think ultimate question is, how load/use templates (which in single file) node? or compiling them incorrectly? should wrap iifes in module.exports? did accomplished nothing. how i'm requiring template file @ head of .js file:

var dust = require('dustjs-linkedin'); require('dustjs-helpers'); require('templates/all.js'); var json = require('json3'); 

when load template file via "var templates = require(...);" call or require() directly first "dust not defined" error, when prepend "var dust = require('dustjs-linkedin');" templates file error stating object has no write method.

object function (){dust.register("index",body_0);var blocks={"body":body_1};function body_0(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.partial("layouts/mainfull",ctx,{});}function body_1(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.write("<ul>").section(ctx.get(["topnavigation"], false),ctx,{"block":body_2},{}).write("</ul>").section(ctx.get(["products"], false),ctx,{"block":body_3},{});}function body_2(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.write("<li>").reference(ctx.get(["title"], false),ctx,"h").write("</li>");}function body_3(chk,ctx){ctx=ctx.shiftblocks(blocks);return chk.reference(ctx.get(["name"], false),ctx,"h");}return body_0;} has no method 'write' 

the question is, why think there no 'write' method? doing wrong trying load this? in theory, each of compiled templates should register dust cache when file loaded , iife executes, keeps throwing "no method 'write'" error. if copy/paste templates directly .js file i'm attempting load them. should wrapping compiled template file "module.exports" code? maybe inside of function? i'm @ loss why isn't working or maybe how compile/load templates. appreciated! thanks!


edit gist of raw templates


edit

that excellent explanation below on accepted answer. still having problem however, seems @ intersection of not understanding dust when .render() called, , fact i'm having in edge.js/.net.

note: compiled templates, semicolons ;), in file requires dust library @ top otherwise aforementioned iifes. on mac, in node.js following works:

var dust = require('dustjs-linkedin'); dust.helpers = require('dustjs-helpers'); require('./templates/all.js');  var myfunction = function(data) {     console.log(dust.cache); }  module.exports = function(data) {     return myfunction(data); } 

i can see templates in cache. however, if change 'myfunction' still sees cache returns undefined:

var dust = require('dustjs-linkedin'); dust.helpers = require('dustjs-helpers'); require('./templates/all.js');  var myfunction = function(data) {     console.log(dust.cache);     return dust.render('index', data, function(err, out) {         return out;     } }  module.exports = function(data) {     return myfunction(data); } 

that's 1 problem. other problem, introduced when use edge.js in .net context, same setup not load templates cache when on mac in straight node.js environment. can load file fine, can output string, when peek @ dust.cache (pita due console.log not working in .net context) returns empty. problem led me try dumping compiled templates array iterating on array calling dust.loadsource on each array item doesn't want work either.

i'm working on cleaning project post github sometime today.

answer 2014-8-21 edit:

now you're talking difference between async , sync.

dust renders templates asynchronously. in fact, that's 1 of main benefits of dust on other templating systems. let's walk through what's happening in second code block:

  1. somewhere you're require-ing code block module. simplicity, let's assume code block in file called /myfunction.js. so, somewhere else, you're saying:

    var myfunction = require('./myfunction'); var output = myfunction({ my: 'model' }); // output === undefined 
  2. myfunction logs dust.cache , returns return value of dust.render

  3. dust.render takes callback , returns undefined (so you're seeing expected behavior)
  4. dust does, calling callback supplied when has rendered template string
  5. your callback returns out didn't call callback—dust did—so return value promptly dropped on floor

what want access template string dust returns callback. way maintain control of callback.

consider following:

// little shortcut since `dustjs-helpers` requires , returns dust anyway var dust = require('dustjs-helpers'); require('./templates/all.js');  // `myfunction` uses dust async, therefore needs async (take callback) var myfunction = function(data, cb) {     console.log(dust.cache);     dust.render('index', data, cb); }  module.exports = myfunction;  // ... , here's example usage ...  var myfunction = require('./myfunction); myfunction({ my: 'model' }, function (err, templatestr) {     if (err) {         // ... dust had problem ...     } else {         // ... `templatestr` ...         console.log(templatestr);     } }); 

regarding second question, i'll wait repo. ;)


edit: guess helps read full question. tried , didn't work. it's problem how templates being generated.

double edit: fixed. add semicolons end of iifes. =p

there few ways can tackle this.

first, if can use view engine can leverage precompiled templates, go it. you'd have have each in own file, , template name have match file path, it's easiest. example, adaro can render precompiled templates. you'd register like:

var dust = require('adaro'); app.engine('js', dust.js()); app.set('view engine', 'js'); app.set('views', __dirname + '/views'); 

next, if don't or can't break templates own files or change names reflect file path, next easiest thing leverage these 2 facts: 1) node caches modules , 2) dustjs-linkedin returns singleton. means if require('dustjs-linkedin') in 1 file, you'll same object in other file you're require('dustjs-linkedin')*. worth mentioning, bit of hack.

so means if @ point dust.register, can dust.render template. you'll have circumvent express' view rendering in order work, it's possible. i've written example , thrown on github short of is:

  1. add reference dust in rendered templates file

    // /templates/combined.js var dust = require('dustjs-linkedin'); // templates below (function () {dust.register('mytemplate', /* ... */})(); 
  2. pull dust route handler , use dust render instead of express

    // /routes/index.js var dust = require('dustjs-linkedin'); module.exports = function (req, res, next) {   // instead of res.render ...   dust.render('mytemplate', {my: 'model'}, function (err, compiled) {     if (err) return next(err);     res.send(compiled);   }); }; 

since you're not using express' handy render methods, use dust's stream interface stream output client instead of buffering rendered template in memory. in fact, streaming reason i'd ever consider using pattern because, though functional workaround, it's bit inelegant , relies on things i'd—personally—recommend against relying on (singletons modules).

another option write own view engine that, rather looking exclusively on file system templates, check dust cache first, expose setup method allow populate cache ahead of time.

finally, if don't of these solutions, check out krakenjs (full disclosure: work on this). it, along it's supporting cast of modules (like kraken-devtools) rid of having think of lot of stuff. try out yeoman generator.

* - node caches modules file path true if require statements resolve same file path. in other words, sub dependent dustjs-linkedin different dustjs-linkedin dependency.


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -