我如何在Nodejs服务器上使用Handlebars渲染静态HTML文件?

4

我在网上找到了很多相关资料,但没有一个能够让我轻松理解的。

目前,我在一个HTML文档中有多个大型<script>标签,其中包含handlebars内容。服务器将此HTML文档发送到客户端,客户端使用来自AJAX调用的数据呈现页面。我希望将整个过程移到服务器端,这样服务器只需要发送静态文件,并在数据更新时重新呈现页面。由于数据每天更改几次,因此它不是硬编码的,我希望在数据更新时运行handlebars编译器对HTML文档进行编译。

是否可以通过函数将具有handlebars模板的HTML文档放入<script>标签中,以生成填充有数据的新HTML文件?

以下是我在Node服务器上运行的app.js文件中的代码,它并未实现我想要的功能:

function registerHelpers(callback){
  Handlebars.registerHelper('equal', function(lvalue, rvalue, options) {
    if (arguments.length < 3)
        throw new Error("Handlebars Helper equal needs 2 parameters");
    if( lvalue!=rvalue ) {
        return options.inverse(this);
    } else {
        return options.fn(this);
    }

  });

  Handlebars.registerHelper('trim', function(text) {
    text = text.replace(/ /g, '');
    return new Handlebars.SafeString(text);
  });

  callback();
}

function buildHomePage() {
  var source = require(__dirname + '/public/home.handlebars');
  var template = Handlebars.precompile(source);
  var collection = db.get('datalist'); //Monk call to MongoDB
  collection.find({}, function (err, docs){
    var result = template(docs);
    console.log(result)
    var fs = require('fs');
        fs.writeFile("test.html", result, function(err) {
        if(err) {
          console.log(err);
        }
    });
  });
};

registerHelpers(buildHomePage);

如果我理解正确的话,你正在描述的是在服务器上呈现初始页面并将HTML发送到客户端,而当数据更新时,在客户端重新呈现整个页面。看起来过于复杂,因为你必须支持两个完整的呈现路径和代码片段。我建议你要么最初在服务器端进行呈现,然后在客户端中手术式地插入更新/修改(而不是重新呈现整个页面),要么始终在客户端中进行呈现,无论是最初还是在获取更新时。 - jfriend00
你可以将数据作为Javascript数据放入<script>标签中,以此来避免初始的ajax调用,然后你的初始渲染可以使用那里的数据。这样,只有一种类型的渲染。当页面首次渲染时,它是从随页面一起传递的Javascript数据进行渲染的。当稍后重新渲染页面时,仍然使用相同的渲染机制,但是从另一个来源获取数据(可能是Ajax调用或WebSocket消息)。 - jfriend00
另外,为什么您的服务器会将 test.html 写入文件系统?对于处理多个用户的服务器,您不能这样做(将硬编码的文件名作为请求处理程序的一部分进行渲染)。来自多个用户的多个请求将互相干扰。通常,您会将其呈现为 Javascript 字符串(您已经这样做了),然后将该字符串作为 http 响应发送。无需将数据放入文件系统中。 - jfriend00
@jfriend00 我觉得我可能表达不清楚。我想从我的handlebars模板生成一个静态HTML文件。然后服务器将提供静态HTML文件,而没有任何handlebars模板。它会生成这个HTML文件一次,然后提供这个HTML文件,直到创建一个新的HTML文件。希望这样更清楚明白? - WaterlessStraw
1个回答

12

下面的内容可以将handlebars渲染为静态html。运行node example.js。在此之前,您可能需要运行npm install --save handlebars

var fs = require('fs');
var Handlebars = require('handlebars');

function render(filename, data)
{
  var source   = fs.readFileSync(filename,'utf8').toString();
  var template = Handlebars.compile(source);
  var output = template(data);
  return output;
}

var data = JSON.parse(fs.readFileSync("./data/strings.json", 'utf8'));

var result = render('./templates/somefile.html', data);

console.log(result);

如果您的把手模板很简单,只有字符串替换,您可以使用underscore.js完成。假设这个例子被命名为“generate.js”

var fs = require('fs');
var _ = require('underscore');
_.templateSettings.interpolate = /\{\{(.+?)\}\}/g;

function render(filename, data)
{
  var source   = fs.readFileSync(filename,'utf8').toString();
  var compiled = _.template(source);
  return compiled(data);
}

var data = JSON.parse(fs.readFileSync("./data/strings.json", 'utf8'));

var result = render('./templates/somefile.html', data);

console.log(result);

运行node generate.js将模板渲染结果输出到控制台。在此之前,您可能需要执行npm install --save underscore


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接