Reputation: 1037
We've got handlebars running in a backend nodejs application for templating various messages that get sent.
Error: You must pass a string or Handlebars AST to Handlebars.compile. You passed <html>
<head>
... extremely long markup
at Object.compile (/Users/guscrawford/rollick-management-console/deployd/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js:501:11)
at HandlebarsEnvironment.hb.compile (/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.
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.compile(inner)({name:'Gus'});
console.log('Output:');
console.log(output)
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.
Upvotes: 2
Views: 6658
Reputation: 1
This solved it for me:
const template:Handlebars.TemplateDelegate | null = Handlebars.compile(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.
Upvotes: 0
Reputation: 1037
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
Upvotes: 13
Reputation: 40444
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.compile. 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.compile. You passed ' + input);
Upvotes: 2