如何将JS字符串解释为文件或在Bundlebars中使用字符串

时间:2015-03-02 02:01:05

标签: javascript

我正在使用Bundlebars,这是一个出色的库,可以使用给定的数据将把手模板转换为静态html。

例如,

var data = {name: 'foo', location: 'bar'}
bb.compile('template.hbs', data)

但是,对于html字符串,Bundlebars看起来并不相同(例如,

"<h1>Hello {{name}} </h1>"

所以我有两个截然不同的问题;任何一个都会有所帮助:

  1. 您是否可以在不创建实际文件的情况下将html文件编码为变量,以便将变量本身解释为文件? [我认为Bundlebars试图使用&#39; open&#39;读取文件的功能]。

  2. Bundlebars可以与字符串本身一起使用而不是要读取的文件吗?

1 个答案:

答案 0 :(得分:0)

  

可以将Bundlebars与字符串本身一起使用而不是要读取的文件吗?

根据GitHub上的Bundlebars API页面,.compile()期望第一个参数是文件名,而不是HTML字符串,并且它不会显示可能采用HTML字符串的其他API。

我不太了解Bundlebars和Handlebars之间的关系(看起来Bundlebars在内部使用了Handlebars),但如果您可以使用它,handlebars API会使用一串HTML。

你应该只能require('handlebars.js')并使用把手本身来获取字符串数据。该模块本身已经被Bundlebars加载,因此它已经可用并且在模块缓存中。


  

您可以在不创建实际文件的情况下将html文件编码为   变量使得变量本身被解释为文件? [ 一世   想想Bundlebars会尝试使用&#39; open&#39;读取文件的功能]。

我不知道Javascript中有什么方法可以创建附加到特定文件名的虚拟文件。如果您使用的是node.js,则可以创建自定义流,但是您需要一个允许您将已打开的流传递给它的接口,而不仅仅是文件名字符串。问题是,当您将文件名字符串传递给Bundlebars时,它最终会在其上调用fs.readFile(),然后调用fs.open()fs.read()并且没有内置的挂钩拦截所有这些系统调用,以防止它们进入文件系统。


嗯,新想法......我想你可以用你自己的函数调用fs.readFile()来替换bb.compile(),这个函数可以检测某个文件名并替换结果而无需进入文件系统。这显然是一个巨大的黑客,它取决于你知道Bundlebars呼叫fs.readFile()以便你需要替换它。

警告,这是一个巨大的黑客攻击(我建议找一个更好的方法来解决你的问题):

(function(orig) {
   fs.readFile = function(path, options, cb) {
       // see if it looks like there is HTML in the path
       if (path.indexOf("<") !== -1 && path.indexOf(">") !== -1) {
          // treat this as a string of HTML
          setTimeout(function() {
              // call the completion callback with the path as the 
              // contents of the file
              cb(0, path);
          }, 1);
       } else {
           return orig.apply(fs, arguments);
       }
   };
})(fs.readFile);