Pasar variables a través de manillares parciales

Actualmente me ocupo de handlebars.js en una aplicación express.js. Para mantener las cosas modulares, dividí todas mis plantillas en parciales.

Mi problema : no pude encontrar una forma de pasar variables a través de una invocación parcial. Digamos que tengo un parcial que se ve así:

Headline

Lorem ipsum

Supongamos que registré este parcial con el nombre ‘myPartial’. En otra plantilla, puedo decir algo como:

 
{{> myPartial}}

Esto funciona bien, el parcial se representará como se espera y soy un desarrollador feliz. Pero lo que ahora necesito es una forma de pasar diferentes variables a través de esta invocación, para verificar dentro de un parcial, por ejemplo, si se da un título o no. Algo como:

 
{{#if headline}}

{{headline}}

{{/if}}

Lorem Ipsum

Y la invocación debería verse más o menos así:

 
{{> myPartial|'headline':'Headline'}}

más o menos.

Sé que puedo definir todos los datos que necesito antes de representar una plantilla. Pero necesito una forma de hacerlo, como acabo de explicar. ¿Hay alguna manera posible?

Los parciales de manillar toman un segundo parámetro que se convierte en el contexto para el parcial:

 {{> person this}} 

En las versiones v2.0.0 alpha y posteriores, también puede pasar un hash de parámetros con nombre:

 {{> person headline='Headline'}} 

Puede ver las pruebas para estos escenarios: https://github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#L456-L462 https://github.com/wycats/handlebars.js/ blob / e290ec24f131f89ddf2c6aeb707a4884d41c3c6d / spec / partials.js # L26-L32

Esto es muy posible si escribe su propio ayudante. Estamos utilizando un $ helper personalizado para lograr este tipo de interacción (y más):

 /*/////////////////////// Adds support for passing arguments to partials. Arguments are merged with the context for rendering only (non destructive). Use `:token` syntax to replace parts of the template path. Tokens are replace in order. USAGE: {{$ 'path.to.partial' context=newContext foo='bar' }} USAGE: {{$ 'path.:1.:2' replaceOne replaceTwo foo='bar' }} ///////////////////////////////*/ Handlebars.registerHelper('$', function(partial) { var values, opts, done, value, context; if (!partial) { console.error('No partial name given.'); } values = Array.prototype.slice.call(arguments, 1); opts = values.pop(); while (!done) { value = values.pop(); if (value) { partial = partial.replace(/:[^\.]+/, value); } else { done = true; } } partial = Handlebars.partials[partial]; if (!partial) { return ''; } context = _.extend({}, opts.context||this, _.omit(opts, 'context', 'fn', 'inverse')); return new Handlebars.SafeString( partial(context) ); }); 

Por las dudas, esto es lo que hice para obtener argumentos parciales, más o menos. Creé un pequeño ayudante que toma un nombre parcial y un hash de parámetros que se pasarán al parcial:

 Handlebars.registerHelper('render', function(partialId, options) { var selector = 'script[type="text/x-handlebars-template"]#' + partialId, source = $(selector).html(), html = Handlebars.compile(source)(options.hash); return new Handlebars.SafeString(html); }); 

La clave aquí es que los ayudantes de Handlebars aceptan un hash de argumentos tipo Ruby . En el código auxiliar, se incluyen como parte de las últimas options argumento de la función en su miembro hash . De esta forma, puede recibir el primer argumento, el nombre parcial, y obtener los datos después de eso.

Entonces, es probable que desee devolver Handlebars.SafeString del helper o usar “triple-stash” – {{{ – para evitar que doble escape.

Aquí hay un escenario de uso más o menos completo:

    

Espero que esto ayude a alguien. 🙂

Esto también se puede hacer en versiones posteriores de manillares utilizando la notación key=value :

  {{> mypartial foo='bar' }} 

Permitiéndole pasar valores específicos a su contexto parcial.

Referencia: contexto diferente para el parcial # 182

Parece que quieres hacer algo como esto:

 {{> person {another: 'attribute'} }} 

Yehuda ya te dio una manera de hacer eso:

 {{> person this}} 

Pero para aclarar:

Para dar a su parcial sus propios datos, simplemente déle su propio modelo dentro del modelo existente, así:

 {{> person this.childContext}} 

En otras palabras, si este es el modelo que le está dando a su plantilla:

 var model = { some : 'attribute' } 

A continuación, agregue un nuevo objeto para dar al parcial:

 var model = { some : 'attribute', childContext : { 'another' : 'attribute' // this goes to the child partial } } 

childContext convierte en el contexto de lo parcial, como dijo Yehuda: en eso, solo ve el campo como another , pero no ve (o le importa un poco el campo). Si tenía una id en el modelo de nivel superior y repite la id nuevamente en el childContext, eso funcionará bien ya que el parcial solo ve lo que hay dentro de childContext .

La respuesta aceptada funciona muy bien si solo quiere usar un contexto diferente en su parcial. Sin embargo, no le permite hacer referencia al contexto principal. Para pasar múltiples argumentos, necesita escribir su propio ayudante. Aquí hay un ayudante de trabajo para Handlebars 2.0.0 (la otra respuesta funciona para las versiones <2.0.0 ):

 Handlebars.registerHelper('renderPartial', function(partialName, options) { if (!partialName) { console.error('No partial name given.'); return ''; } var partial = Handlebars.partials[partialName]; if (!partial) { console.error('Couldnt find the compiled partial: ' + partialName); return ''; } return new Handlebars.SafeString( partial(options.hash) ); }); 

Luego, en su plantilla, puede hacer algo como:

 {{renderPartial 'myPartialName' foo=this bar=../bar}} 

Y en su parcialidad, podrá acceder a esos valores en un contexto como:

 
{{foo}}

Sí, llegué tarde, pero puedo agregar para los usuarios de Ensamblar : puede usar el "parseJSON" http://assemble.io/helpers/helpers-data.html . (Descubierto en https://github.com/assemble/assemble/issues/416 ).