我正在尝试创建一个函数,该函数采用模板名,并能够将呈现的模板作为字符串返回。我正在使用linkedin版的“灰尘”。我正在预编译模板(使用咕噜声任务)到一个文件中,如下所示:
(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 by 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;})()我认为我的最终问题是,如何从节点加载/使用这些模板(在它们的单个文件中)?还是我编错了?我应该把这些IIFE包在一个module.exports中吗?我这么做了,但什么也没做。这就是我如何在我的.js文件的开头要求模板文件:
var dust = require('dustjs-linkedin');
require('dustjs-helpers');
require('templates/all.js');
var JSON = require('json3');当我通过"var template =require(.)“加载模板文件时,直接调用或要求()它时,首先会得到一个”尘埃未定义“错误,然后当我将"var dust =require(‘’‘)”添加到模板文件时,我会得到一个错误,说明对象没有写方法。
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'问题是,为什么它认为没有‘写’方法?我装这个做错了什么?理论上,每个编译好的模板都应该在文件加载和执行时将自己注册到尘缓存中,但是它总是抛出“compiled‘and’”错误。即使我将这些模板直接复制/粘贴到我试图加载它们的.js文件中,它也会这样做。我应该用"module.exports“代码包装已编译的模板文件吗?也许是在一个功能里面?我不知道为什么这不起作用,甚至可能不知道如何正确编译/加载模板。任何帮助都是非常感谢的!谢谢!
编辑 原始模板要点
编辑
这是下面对已被接受的答案的一个很好的解释。然而,我仍然有一个问题,但它似乎处于一个交叉点,无法正确理解调用.render()时灰尘会做什么,而且我必须在Edge.js/.NET中这样做。
注意:带有分号的已编译模板在一个文件中,它需要顶部的尘埃库,但在其他情况下只是上述。在我的Mac上,在Node.js中有以下工作:
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);
}我可以在缓存中看到模板。但是,如果我将“myFunction”改为“”,它仍然会看到缓存,但返回未定义的:
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);
}这是个问题。在.NET上下文中使用.NET时引入的另一个问题是,相同的设置不会像在直接的node.js环境中在Mac上那样将模板加载到缓存中。我可以很好地加载文件,甚至可以将其输出为字符串,但当我查看dust.cache (由于console.log在.NET上下文中不工作)时,它返回为空。正是这个问题促使我尝试将编译好的模板转储到数组中,然后迭代对每个数组项调用dust.loadSource的数组,但这也不想工作。
我正在清理这个项目,以便在今天的某个时候发布到GitHub。
发布于 2014-08-20 22:11:10
回复2014-8-21编辑
现在您正在讨论异步和同步之间的区别。
尘埃异步地呈现模板。事实上,这是灰尘对其他模板系统的主要好处之一。让我们来看看在第二个代码块中发生了什么:
require-ing,该代码块是一个模块。为了简单起见,让我们假设代码块位于一个名为/myFunction.js的文件中。所以,在别的地方,你是说:
var myFunction =需要量(‘./myFunction’);var output = myFunction({ my:'Model‘});// output ===未定义myFunction记录dust.cache并返回dust.render的返回值。dust.render接受回调并立即与undefined一起返回(因此您将看到预期的行为)out,但您没有调用您的回调-灰尘调用-因此您的返回值立即下降到地板上。您要做的是获得对模板字符串的访问权,然后返回给回调。唯一的方法是保持对回调的控制。
请考虑以下几点:
// a little shortcut since `dustjs-helpers` requires and returns dust anyway
var dust = require('dustjs-helpers');
require('./templates/all.js');
// `myFunction` uses dust which is async, therefore it needs to be async (take a callback)
var myFunction = function(data, cb) {
console.log(dust.cache);
dust.render('index', data, cb);
}
module.exports = myFunction;
// ... and here's example usage ...
var myFunction = require('./myFunction);
myFunction({ my: 'Model' }, function (err, templateStr) {
if (err) {
// ... dust had a problem ...
} else {
// ... do something with `templateStr` like ...
console.log(templateStr);
}
});关于第二个问题,我将等待回购。;)
编辑:我想阅读完整的问题会有帮助。你试过了但没成功。这是一个如何生成模板的问题。
双编辑:固定。在IIFE的末尾添加分号。=P
有几种方法可以解决这个问题。
首先,如果您可以使用一个可以利用预编译模板的视图引擎,那么就选择它。您必须将每个文件都包含在自己的文件中,模板名必须与文件路径匹配,但这当然是最简单的。例如,阿达罗可以呈现预编译模板。你可以把它注册如下:
var dust = require('adaro');
app.engine('js', dust.js());
app.set('view engine', 'js');
app.set('views', __dirname + '/views');接下来,如果您不能或不能将这些模板分解到它们自己的文件中,或者更改名称以反映文件路径,那么接下来最简单的事情就是利用这两个事实: 1)节点缓存模块,2) dustjs-linkedin返回一个单例。这意味着,如果在一个文件中使用require('dustjs-linkedin'),则在任何其他文件中都会得到与require('dustjs-linkedin')*相同的对象。值得一提的是,这是个小问题。
这意味着,如果在任何时候你dust.register,你可以dust.render那个模板。您必须绕过express的视图呈现,才能使其工作,但这是可能的。我已经编写了一个示例和把它扔到github上,但它的不足是:
因为您没有使用express的方便的呈现方法,所以可以使用dust的流接口将输出流流到客户端,而不是在内存中缓冲呈现的模板。事实上,流媒体是我考虑使用这种模式的唯一原因,因为尽管这是一个功能性的解决方案,但它有点不优雅,并且依赖于我个人建议不要依赖的东西(模块中的单件)。
另一种选择是编写您自己的视图引擎,它可以首先检查灰尘缓存,然后公开一个允许您提前填充缓存的setup方法,而不是只在文件系统上查找模板。
最后,如果您不喜欢这些解决方案中的任何一个,请查看克拉肯杰 (完全公开:我致力于此)。除了支持模块(比如kraken-devtools)之外,它还摆脱了很多这些东西。用约曼发电机轻松地尝试一下。
*-节点缓存模块文件路径,因此只有当您的require语句解析到相同的文件路径时,这才是正确的。换句话说,一个子依赖的尘埃-linkedin将不同于您的灰尘-linkedin依赖。
发布于 2014-08-23 18:16:16
因此,我将回答我自己的问题,这将适用于,我的具体问题,但我不会试图提供一个全面的答案,加载Dust.js模板的一般问题,让查尔斯做了。他将保留接受的答案,我的回答可能是对试图手动呈现预编译模板的人的一个脚注警告。特别是预先编译成一个文件的模板。也可能是Adaro can的一个开关,希望通过对多个文件的解析获得更高的效率。
最终,我的问题是,单个文件“templates.js”以错误的顺序加载已编译的模板。因此,index.js使用了一个布局(实际上只是一个花哨的部分),但是没有为索引模板加载布局模板来尝试作为布局使用。
对我来说,解决办法是改变我的尘埃落定的任务:
[{
"templates/all.js": ["theme/**/*.dust"]
}]对此:
[{
"templates/all.js": [
"theme/partials/[singletons]/*.dust",
"theme/partials/*.dust",
"theme/layouts/*.dust",
"theme/*.dust"
]
}]这将向后遍历目录树,执行模板只能使用部分(即对等方或后代)的结构。这实际上是对编译器说的:“首先给我个人(最多重用)的部分,然后是组件级的部分,然后是我的布局(它将是部分的主要使用者,以及顶级的灰尘文件),然后是我的顶层灰尘文件,这些文件可以被看作页面”。页面将是布局的使用者和服务器端模板请求的入口点。
令人烦恼的是单身区。不可避免地,一个部分将要求它的对等点,并且该对等点将用字母前面的一个字母命名,该字母在字母表中表示为分部。这将导致与索引模板相同的情况,即在加载布局模板之前需要布局模板。除非我错过了什么,否则就会悄无声息地失败。它将成功地将每个模板加载到缓存中,但是需要尚未加载模板的模板将无法正确编译,并且在调用时无法呈现。
https://stackoverflow.com/questions/25365396
复制相似问题