パーシャルを登録しようとしています。ドキュメントによると、次のように行う必要があります。
var partialString = fs.readFileSync(filename), {encoding: 'utf8'})
var compiledPartial = handlebars.precompile(partialString)
var template = handlebars.template(compiledPartial)
handlebars.registerPartial('stuff', template)
ただし、 .template()
メソッドは次のエラーを生成します。
Error: Unknown template object: string
上記のcompiledPartial
は、実際にはオブジェクトのように見える文字列であることがわかります。
{"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<div>Stuff</div>\n";
},"useData":true}
WTF?
ノード0.10.25、ハンドルバー2.0.0
precompiler
メソッドはテンプレートをシリアル化するためのものであり、次にtemplate
メソッドを使用してクライアント上でテンプレートを復元します。 同じプロセスでテンプレートを評価しようとしている場合は、 Handlebars.compile
直接使用する必要があります。
答えてくれてありがとう。 サーバー側でハンドルバーのみを使用している場合は、コンパイルされていない部分文字列のみをregisterPartial()
メソッドに渡すことができるため、ドキュメントはクライアント側でハンドルバーを使用することを目的としているようです。
テンプレートをプリコンパイルし(新しいコンテキストで再レンダリングする必要がある場合に備えてクライアントに配信し)、HTMLにレンダリングする(ちらつきが目立たないようにする)必要があるサーバー側アプリケーションを作成しています。クライアントでの遅延+改善されたSEO)。 precompile
とcompile
両方を別々に呼び出す必要があるか、シリアル化されたプリコンパイラ出力をeval
する必要があるようです。 これらのアプローチはどちらもあまりエレガントではないので、何かが足りないのでしょうか、それともアプリケーションが異常なのでしょうか。 (ところで、このアプリケーションはJavaで書かれていますが、テンプレート部分に組み込みの[Rhino / Nashorn] JavaScriptエンジンを使用しています。うまくいけば、それは問題ではありません。)
他の誰かがプリコンパイルの
var templateSources = {
hi: "Hi, {{name}}.",
bye: "Goodbye, {{name}}."
};
var compiledTemplates = {};
var serializedTemplates = {};
var deserializedTemplates = {};
Object.keys(templateSources).forEach(function(name) {
// Use compile method to generate actual executable template (function)
compiledTemplates[name] = Handlebars.compile(templateSources[name]);
// Use precompile method to generate serialized JS (string)
serializedTemplates[name] = Handlebars.precompile(templateSources[name]);
// If we really want, we can deserialize these
deserializedTemplates[name] = Handlebars.template(evalPrecompiledTemplate(serializedTemplates[name]));
});
// (Yes, I know eval is dangerous)
function evalPrecompiledTemplate(s) {
return eval("(function(){return " + s + "}());");
}
// Quick demonstration that these template functions work the same
var context = {
name: "John Smith"
};
// Output:
// Rendering template named hi with context: Object {name: "John Smith"}
// Hi, John Smith.(compiled)
// Hi, John Smith.(precompiled/deserialized)
// Rendering template named bye with context: Object {name: "John Smith"}
// Goodbye, John Smith.(compiled)
// Goodbye, John Smith.(precompiled/deserialized)
Object.keys(templateSources).forEach(function(name) {
console.log("Rendering template named " + name + " with context:", context);
console.log(compiledTemplates[name](context) + "(compiled)");
console.log(deserializedTemplates[name](context) + "(precompiled/deserialized)");
});
@jacobqは、コンパイルとプリコンパイルを呼び出す必要があります。 この2つで生成されるコードは大きく異なり、toStringなどを実行しようとするとコンパイル出力などで機能するとは思いません。
最も参考になるコメント
テンプレートをプリコンパイルし(新しいコンテキストで再レンダリングする必要がある場合に備えてクライアントに配信し)、HTMLにレンダリングする(ちらつきが目立たないようにする)必要があるサーバー側アプリケーションを作成しています。クライアントでの遅延+改善されたSEO)。
precompile
とcompile
両方を別々に呼び出す必要があるか、シリアル化されたプリコンパイラ出力をeval
する必要があるようです。 これらのアプローチはどちらもあまりエレガントではないので、何かが足りないのでしょうか、それともアプリケーションが異常なのでしょうか。 (ところで、このアプリケーションはJavaで書かれていますが、テンプレート部分に組み込みの[Rhino / Nashorn] JavaScriptエンジンを使用しています。うまくいけば、それは問題ではありません。)他の誰かがプリコンパイルの