admin管理员组文章数量:1245119
Premise
We've got handlebars running in a backend nodejs application for templating various messages that get sent.
Handlebarspile throws this exception (when piling templates from partials)
Error: You must pass a string or Handlebars AST to Handlebarspile. You passed <html>
<head>
... extremely long markup
at Objectpile (/Users/guscrawford/rollick-management-console/deployd/node_modules/handlebars/dist/cjs/handlebars/piler/piler.js:501:11)
at HandlebarsEnvironment.hbpile (/Users/guscrawford/rollick-management-console/deployd/node_modules/handlebars/dist/cjs/handlebars.js:39:40)
at Object.invokePartialWrapper [as invokePartial] (/Users/guscrawford/rollick-management-console/deployd/node_modules/handlebars/dist/cjs/handlebars/runtime.js:71:44)
... additional stack trace through to dpd, bluebird etc.
Cannot replicate through isolation
Go ahead and try setting up a scrap project:
yarn add handlebars handlebars-helper-ternary handlebars-helpers handlebars.numeral
Then run this script in nodejs:
const handlebars = require('handlebars'),
numeralHelper = require('handlebars.numeral'),
ternaryHelper = require('handlebars-helper-ternary'),
helpers = require('handlebars-helpers')({
handlebars: handlebars
});
console.log(`Testing...`);
const base = `
<html>
<body style="font-family:'Segoe UI', Tahoma, Geneva, Verdana, 'sans-serif'; font-size: larger;">
{{>@partial-block }}
<td style="text-align: center; padding: 24px;">
Copyright 2018 My Company, Inc. All rights reserved.
</body>
</html>
`;
const inner = `
{{#>base}}
{{subscriber.name}},
{{member.name}} has received a notifier from {{subscriber.name}}.
Click the link below to review!.
<a href='{{link}}'>Go!</a>
Thank you,
My Company
{{/base}}
`;
numeralHelper.registerHelpers(handlebars);
handlebars.registerHelper('ternary', ternaryHelper);
handlebars.registerHelper("moduloIf", function (index_count, mod, block) {
if (index_count > 0 && parseInt(index_count) % (mod) === 0) {
return block.fn(this);
} else {
return block.inverse(this);
}
});
handlebars.registerHelper("substitute", function(a, options) {
try {
function index(obj,i) { return obj ? obj[i] : {} }
let data = a.split('.').reduce(index, this);
if (data && typeof data === 'string') return data;
else return options.fn(this);
} catch (e) {
console.log('substitute helper:' + e);
}
});
handlebars.registerPartial('base',base)
var output = handlebarspile(inner)({name:'Gus'});
console.log('Output:');
console.log(output)
Further consideration
In actuality we have the handlebars require
wrapped in another module with code run against the handlebars instance as illustrated in the sample script. We're exporting the handlebars instance.
Premise
We've got handlebars running in a backend nodejs application for templating various messages that get sent.
Handlebars.pile throws this exception (when piling templates from partials)
Error: You must pass a string or Handlebars AST to Handlebars.pile. You passed <html>
<head>
... extremely long markup
at Object.pile (/Users/guscrawford/rollick-management-console/deployd/node_modules/handlebars/dist/cjs/handlebars/piler/piler.js:501:11)
at HandlebarsEnvironment.hb.pile (/Users/guscrawford/rollick-management-console/deployd/node_modules/handlebars/dist/cjs/handlebars.js:39:40)
at Object.invokePartialWrapper [as invokePartial] (/Users/guscrawford/rollick-management-console/deployd/node_modules/handlebars/dist/cjs/handlebars/runtime.js:71:44)
... additional stack trace through to dpd, bluebird etc.
Cannot replicate through isolation
Go ahead and try setting up a scrap project:
yarn add handlebars handlebars-helper-ternary handlebars-helpers handlebars.numeral
Then run this script in nodejs:
const handlebars = require('handlebars'),
numeralHelper = require('handlebars.numeral'),
ternaryHelper = require('handlebars-helper-ternary'),
helpers = require('handlebars-helpers')({
handlebars: handlebars
});
console.log(`Testing...`);
const base = `
<html>
<body style="font-family:'Segoe UI', Tahoma, Geneva, Verdana, 'sans-serif'; font-size: larger;">
{{>@partial-block }}
<td style="text-align: center; padding: 24px;">
Copyright 2018 My Company, Inc. All rights reserved.
</body>
</html>
`;
const inner = `
{{#>base}}
{{subscriber.name}},
{{member.name}} has received a notifier from {{subscriber.name}}.
Click the link below to review!.
<a href='{{link}}'>Go!</a>
Thank you,
My Company
{{/base}}
`;
numeralHelper.registerHelpers(handlebars);
handlebars.registerHelper('ternary', ternaryHelper);
handlebars.registerHelper("moduloIf", function (index_count, mod, block) {
if (index_count > 0 && parseInt(index_count) % (mod) === 0) {
return block.fn(this);
} else {
return block.inverse(this);
}
});
handlebars.registerHelper("substitute", function(a, options) {
try {
function index(obj,i) { return obj ? obj[i] : {} }
let data = a.split('.').reduce(index, this);
if (data && typeof data === 'string') return data;
else return options.fn(this);
} catch (e) {
console.log('substitute helper:' + e);
}
});
handlebars.registerPartial('base',base)
var output = handlebars.pile(inner)({name:'Gus'});
console.log('Output:');
console.log(output)
Further consideration
In actuality we have the handlebars require
wrapped in another module with code run against the handlebars instance as illustrated in the sample script. We're exporting the handlebars instance.
3 Answers
Reset to default 13The string was a Buffer
Despite logging typeof
the template string I was passing as a string, the output of readFileAsync
without passing an encoding is a raw node Buffer.
Duh
The error is clear, you're passing something that isn't a string or AST.
This is the only way handlebars throws that error.
if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
throw new Exception('You must pass a string or Handlebars AST to Handlebars.pile. You passed ' + input);
}
You're probably passing an object
, with a toString
method, that's why you see:
You passed <html>
<head>
... extremely long markup
const input = {
toString() {
return `<html>
<head>`;
}
}
console.log('You must pass a string or Handlebars AST to Handlebars.pile. You passed ' + input);
This solved it for me:
const template:Handlebars.TemplateDelegate | null = Handlebars.pile(new XMLSerializer().serializeToString(your html document or string));
console.log(template({your_key : "your_value"}))
It probably converts a document
type to an XML
string representing a DOM tree.
Javascript is a bit hard to deal with.
本文标签:
版权声明:本文标题:javascript - Handlebars.compile throws an exception 'Error: You must pass a string or Handlebars AST to Handlebars.compi 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740224721a2244474.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论