Handlebars.js: рддреНрд░реБрдЯрд┐: рдЕрдЬреНрдЮрд╛рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ: .template () рдХреЗ рд╕рд╛рде рдкреНрд░реАрдХрдВрдкреАрд▓реНрдб рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╕реНрдЯреНрд░рд┐рдВрдЧ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 12 рджрд┐рд╕ре░ 2014  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: handlebars-lang/handlebars.js

рдореИрдВ рдЖрдВрд╢рд┐рдХ рдкрдВрдЬреАрдХрд░рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЬреЛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЗрд╕ рддрд░рд╣ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:

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}

рдбрдмреНрд▓реНрдпреВрдЯреАрдПрдл?

рдиреЛрдб 0.10.25, рд╣реИрдВрдбрд▓рдмрд╛рд░реНрд╕ 2.0.0

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВ рдПрдХ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ рдЬрд┐рд╕реЗ рджреЛрдиреЛрдВ рдкреНрд░реАрдХрдВрдкрд╛рдЗрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░реЗрдВ рдпрджрд┐ рдЙрдиреНрд╣реЗрдВ рдирдП рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ) рдФрд░ рдЙрдиреНрд╣реЗрдВ HTML рдореЗрдВ рднреА рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВ (рдХрдо рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдЭрд┐рд▓рдорд┐рд▓рд╛рд╣рдЯ рдХреЗ рд▓рд┐рдП / рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рджреЗрд░реА + рдмреЗрд╣рддрд░ SEO)ред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдпрд╛ рддреЛ precompile рдФрд░ compile рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрд╛ рдореБрдЭреЗ рдХреНрд░рдордмрджреНрдз рдкреНрд░реАрдХрдВрдкреЗрд▓рд░ рдЖрдЙрдЯрдкреБрдЯ eval рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрди рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдмрд╣реБрдд рд╣реА рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рддреЛ рдХреНрдпрд╛ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реИ рдпрд╛ рдореЗрд░рд╛ рдЖрд╡реЗрджрди рд╕рд┐рд░реНрдл рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИ? (рдмреАрдЯреАрдбрдмреНрд▓реВ, рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдЯреЗрдореНрдкрд▓реЗрдЯрд┐рдВрдЧ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд░реНрдорд┐рдд [рд░рд╛рдЗрдиреЛ/рдирд╛рд╢реЛрд░реНрди] рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ; рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред)

рдЕрдЧрд░ рдХрд┐рд╕реА рдФрд░ рдХреЛ рдкреНрд░реАрдХрдВрдкрд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рд╕реЗ рднреНрд░рдорд┐рдд рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рдШрд╛рдпрд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдореИрдВрдиреЗ рдпрд╣ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдЦрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВрдиреЗ рдЗрд╕реЗ рдЗрд╕рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рдЧрд▓рдд рдХрд░ рд░рд╣рд╛ рдерд╛ред)

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)");
});

рд╕рднреА 4 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

precompiler рдкрджреНрдзрддрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рд╣реИ рдФрд░ рдлрд┐рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рдЗрд╕реЗ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП template рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдЙрд╕реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЛ рд╕реАрдзреЗ Handlebars.compile рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЬрд╡рд╛рдм рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдореЗрдВ рд╣реИрдВрдбрд▓рдмрд╛рд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕рдХреНрд╖рдо рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрджрд┐ рдЖрдк рдХреЗрд╡рд▓ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рд╣реИрдВрдбрд▓рдмрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ registerPartial() рд╡рд┐рдзрд┐ рдореЗрдВ рдХреЗрд╡рд▓ рдЕрд╕рдореНрдмрджреНрдз рдЖрдВрд╢рд┐рдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред

рдореИрдВ рдПрдХ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ рдЬрд┐рд╕реЗ рджреЛрдиреЛрдВ рдкреНрд░реАрдХрдВрдкрд╛рдЗрд▓ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░реЗрдВ рдпрджрд┐ рдЙрдиреНрд╣реЗрдВ рдирдП рд╕рдВрджрд░реНрдн рдХреЗ рд╕рд╛рде рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ) рдФрд░ рдЙрдиреНрд╣реЗрдВ HTML рдореЗрдВ рднреА рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВ (рдХрдо рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдЭрд┐рд▓рдорд┐рд▓рд╛рд╣рдЯ рдХреЗ рд▓рд┐рдП / рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рджреЗрд░реА + рдмреЗрд╣рддрд░ SEO)ред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдпрд╛ рддреЛ precompile рдФрд░ compile рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрд╛ рдореБрдЭреЗ рдХреНрд░рдордмрджреНрдз рдкреНрд░реАрдХрдВрдкреЗрд▓рд░ рдЖрдЙрдЯрдкреБрдЯ eval рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрди рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдмрд╣реБрдд рд╣реА рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рддреЛ рдХреНрдпрд╛ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реИ рдпрд╛ рдореЗрд░рд╛ рдЖрд╡реЗрджрди рд╕рд┐рд░реНрдл рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИ? (рдмреАрдЯреАрдбрдмреНрд▓реВ, рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдЯреЗрдореНрдкрд▓реЗрдЯрд┐рдВрдЧ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд░реНрдорд┐рдд [рд░рд╛рдЗрдиреЛ/рдирд╛рд╢реЛрд░реНрди] рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ; рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред)

рдЕрдЧрд░ рдХрд┐рд╕реА рдФрд░ рдХреЛ рдкреНрд░реАрдХрдВрдкрд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рд╕реЗ рднреНрд░рдорд┐рдд рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рдШрд╛рдпрд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдореИрдВрдиреЗ рдпрд╣ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдЦрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВрдиреЗ рдЗрд╕реЗ рдЗрд╕рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рдЧрд▓рдд рдХрд░ рд░рд╣рд╛ рдерд╛ред)

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 рдЖрдк рд╕рдВрдХрд▓рди рдФрд░ рдкреНрд░реАрдХрдВрдкрд╛рдЗрд▓ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЗрдирд░реЗрдЯ рдХреЛрдб рдмрд╣реБрдд рдЕрд▓рдЧ рд╣реИ рдФрд░ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рд╕реЗ рд╕рдВрдХрд▓рди рдЖрдЙрдЯрдкреБрдЯ рдЖрджрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

LengYXin picture LengYXin  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

nknapp picture nknapp  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

jlubean picture jlubean  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

sontek picture sontek  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

morgondag picture morgondag  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ