我的问题很简单:我想编译Handlebars视图然后不渲染它 - 而是我想使用已编译的HTML服务器端。在研究这个问题时,this是我能找到的最接近我的问题的,但除非我误解,否则他们在这个问题上所做的就是创建一个HTML字符串服务器端并用数据填充它。这是不够的,因为我不想创建任何HTML字符串,我真的希望像往常一样将我的HTML保存在.hbs
文件中,然后编译一个视图(即发送它我的变量),然后而不是显示它是一个用户(无论如何都不可能,因为它只是一个API服务器),我想让编译好的HTML将它发送到Mailgun(但是我想将它发送到Mailgun的事实超出了范围,答案应该最好只告诉我如何编译视图,并能够(例如)console.log()
HTML)。
我正在使用Node v9.8.0
的软件包:
如果我需要提供任何其他信息以及我没有包含任何我尝试的示例代码的原因,请告诉我,我真的不知道甚至可以尝试什么。我尝试过的只是let emailHtml = res.render('email/contactReceipt.hbs', { name:req.body.name })
在我的路线中,但这给了我错误Cannot set headers after they are sent to the client
。
旁注:我对Node.js相当新,而且它不是我正常堆栈的一部分。我注意到其他人使用'快递把手'包甚至只是'把手',所以如果我正在使用('hbs')实际上与把手没有任何关系,或者如果我不能通过它实现我想要做的事情,让我知道。
答案 0 :(得分:1)
res.render
接受第三个参数,该参数是包含呈现字符串的回调,而不发送响应,从而避免Headers already sent
错误
res.render(view [, locals] [, callback])
呈现视图并将呈现的HTML字符串发送到客户端。 可选参数:
- locals,一个对象,其属性定义了局部变量 视图。
- 回调,回调函数。如果提供,则返回该方法 可能的错误和渲染的字符串,但不执行 自动回复。发生错误时,该方法将调用next(错误) 内部。
res.render('email/contactReceipt.hbs', { name:req.body.name }, (err, html) => {
if(err)
return console.error(err);
// do whatever you want here with `html`
});
您还可以使用app.render,它类似于res.render
但在全局范围内工作,并且始终采用第三个参数。
app.render('email/contactReceipt.hbs', { name:req.body.name }, (err, html) => {
if(err)
return console.error(err);
// do whatever you want here with `html`
});
或者您可以直接编译模板并随后执行任何操作。
const hbs = require('hbs');
const template = hbs.compile('<h1>{{title}}</h1>');
const html = template({ title: 'Handlebars' });
console.log(html); // <h1>Handlebars</h1>
如果您想从磁盘中读取模板内容,只需使用fs.readFile
并将内容传递给hbs.compile
const hbs = require('hbs');
const fs = require('fs');
const readFile = require('util').promisify(fs.readFile);
async render(file, data) {
const content = await readFile(file, 'utf8');
// Implement cache if you want
const template = hbs.compile(content);
return template(data);
}