como {{ helper1 helper2 text }}
, sabes que a veces solo un ayudante no es suficiente para hacer el trabajo.
Creo que debería haber una forma de anidar expresiones, como esta: {{headerText {{getTitle "my_page"}}}}
.
Eso no es compatible actualmente y no tengo planes de hacerlo.
Sin embargo, teóricamente podrías crear un ayudante que consuma y encadene intencionalmente a otros ayudantes:
{{chain "helper1" "helper2" text}}
Si alguien está interesado, he creado un ayudante de este tipo:
Handlebars.registerHelper('chain', function () {
var helpers = [], value;
$.each(arguments, function (i, arg) {
if (Handlebars.helpers[arg]) {
helpers.push(Handlebars.helpers[arg]);
} else {
value = arg;
$.each(helpers, function (j, helper) {
value = helper(value, arguments[i + 1]);
});
return false;
}
});
return value;
});
Funciona así:
{{chain "taxAdd" "formatPrice" this.product.price}}
@Znarkus que introduce una dependencia a jQuery
@jrajan Solo usé jQuery.each
, siéntete libre de reescribirlo con tus preferencias.
Si alguien está interesado en una versión independiente de jQuery:
Handlebars.registerHelper('chain', function() {
var helpers = [];
var args = Array.prototype.slice.call(arguments);
var argsLength = args.length;
var index;
var arg;
for (index = 0, arg = args[index];
index < argsLength;
arg = args[++index]) {
if (Handlebars.helpers[arg]) {
helpers.push(Handlebars.helpers[arg]);
} else {
args = args.slice(index);
break;
}
}
while (helpers.length) {
args = [helpers.pop().apply(Handlebars.helpers, args)];
}
return args.shift();
});
Vale la pena señalar un problema con ambas implementaciones: si alguno de los argumentos está destinado a ser valores para pasar a un ayudante, pero también resultan ser (coercibles a) cadenas que coinciden con el nombre de un ayudante existente, habrá resultados inesperados.
Aquí hay dos implementaciones. Ambos le permiten tener varios argumentos enviados a cada ayudante, a diferencia de los ejemplos anteriores.
También están escritas en escritura de café y dependen de guiones bajos o lodash.
El primero te permite hacer algo como esto:
{{{chain 'join-strings' 'link-twitter-handles' '@' twitterUsername}}}
Pero algo como esto produciría resultados inesperados:
{{{chain 'join-strings' 'link-twitter-handles' '@' 'join-strings' twitterUsername}}}
Handlebars.registerHelper 'chain', ->
# Get rid of the options hash
args = Array.prototype.slice.call arguments, 0, -1
helpers = []
argsForHelpers = null
value = undefined
_.each args, (arg, i) ->
if Handlebars.helpers[arg]
helpers.push Handlebars.helpers[arg]
else if not value # Only call the helpers once
value = arg
unless argsForHelpers
argsForHelpers = args[i+1..-1]
argsForHelpers.unshift value
_.each helpers, (helper) ->
argsForHelpers[0] = value
value = helper.apply null, argsForHelpers
value
Este segundo ejemplo tiene un separador que permite a chain
dividir los ayudantes de los argumentos.
El ayudante asumirá que cada argumento antes del separador es un ayudante y todos los demás deben pasarse como argumentos a los ayudantes.
Handlebars.registerHelper 'chain', ->
# Get rid of the options hash
args = Array.prototype.slice.call arguments, 0, -1
helpers = []
for arg,i in args
if arg is '--'
argsForHelpers = args.slice i + 1
value = argsForHelpers[0]
break
else
helpers.push Handlebars.helpers[arg]
_.each helpers, (helper) ->
argsForHelpers[0] = value
value = helper.apply null, argsForHelpers
value
Dada esta plantilla:
{{{chain 'join-strings' 'link-twitter-handles' '@' 'join-strings' twitterUsername}}}
y este objeto:
{twitterUsername: 'abc'}
Podríamos esperar una plantilla compilada como esta:
<a href="https://twitter.com/join-stringsabc">@join-stringsabc</a>
Tomé la implementación de
/**
* Takes an arbitrary number of arguments, the first of which is the operation type 'AND' or 'OR'.
* Following that will be a list of block helper names prefixed by '!!'.
* Calls each block helper with the remaining arguments.
*
* <strong i="7">@returns</strong> {string} returns options.fn(this) or options.inverse(this) depending on result of each helper and operation type
*/
Handlebars.registerHelper('chainBlockHelpers', function() {
var index, arg, helperResult, pass,
helpers = [],
args = Array.prototype.slice.call(arguments),
argsLength = args.length,
options = args[argsLength-1],
operation = args.shift(),
passVal = options.fn(this),
failVal = options.inverse(this);
if (operation !== 'AND' && operation !== 'OR')
throw new Error ('chainBlockHelpers only supports "AND" or "OR" operations.')
for (index = 0, arg = args[index]; index < argsLength; arg = args[++index]) {
if (typeof arg == 'string' && arg.startsWith('!!') && Handlebars.helpers[arg.substr(2)]) {
helpers.push(Handlebars.helpers[arg.substr(2)]);
} else {
args = args.slice(index);
break;
}
}
if (operation === 'AND') {
pass = true;
while (helpers.length) {
helperResult = helpers.pop().apply(Handlebars.helpers, args);
if (helperResult == failVal) {
pass = false;
break;
}
}
} else {
pass = false;
while (helpers.length) {
helperResult = helpers.pop().apply(Handlebars.helpers, args);
if (helperResult == passVal) {
pass = true;
break;
}
}
}
return pass ? passVal : failVal;
});
esto parece tener soporte nativo usando algo como:
{{ helper1 (helper2 text) }}
En algunos casos, puede hacer que sus ayudantes funcionen como:
{{#helper1}}{{helper2}}content{{/helper2}}{{/helper1}}
@Znarkus Usando su método, cuando paso dos ayudantes que tienen cadenas seguras aplicadas, mi código se rompe. La primera vez que paso datos, aparece como una cadena, pero el segundo filtro, ¿el valor que se pasa parece ser un objeto? En mi depurador se muestra como 'un salto de línea y luego cadena:' mi valor '; No estoy seguro de qué hace SafeString con el valor, pero pasarlo dos veces no parece funcionar bien.
Handlebars.registerHelper('shortNumber', function (value) {
//return new Handlebars.SafeString(iSpot.number.shortNumber(value)); // Breaks
return iSpot.number.shortNumber(value); // Works
});
Handlebars.registerHelper('asDollars', function (value) {
//return new Handlebars.SafeString(iSpot.number.asDollars(value)); // Breaks
return iSpot.number.asDollars(value); // Works
});
Enfoque de +1 {{pluralize (titleize (humanize schema.name))}}
+1 que parece una sintaxis limpia y agradable.
+1 @amwmedia Funciona perfectamente gracias
El enfoque @amwmedia funciona como un encanto, pero solo sin Handlebars.SafeString()
como @cssagogo mencionado anteriormente.
Entonces puedes hacer algo. me gusta:
{{> partial text=(concat value (default extension 'PDF')) }}
Gracias
Yo mismo me encontré con este problema. Sé que llegué tarde en esto, pero tengo una solución que funcionó para mí. Por favor, perdóneme si esto ya se mencionó (no me tomé el tiempo de verificarlo). Esta no es la mejor solución y técnicamente no es una respuesta directa a su pregunta, pero es una solución al problema (ejecutar múltiples funciones en un valor).
Guardo todas mis funciones auxiliares en un archivo separado. Debido a que están todos en el mismo lugar, puedo pasar el valor a un ayudante y luego simplemente llamar a cualquier otra función que tenga en el archivo de mi función auxiliar. Entonces:
{{ function1 value }}
archivo de ayuda
function2 (value) {
// code
}
function1 (value) {
// code
function2(value)
// code
return value;
}
Por supuesto, esta es una forma sencilla de poder utilizar tantas funciones como desee. Incluso podría designar una función base que actúe como su "encadenamiento".
{{ chainer value }}
archivo de ayuda
function1 (value) {
// code
}
function2 (value) {
// code
}
function3 (value) {
// code
}
function4 (value) {
// code
}
function chainer(value) {
function1(value)
function2(value)
function3(value)
function4(value)
return value;
}
No lo he hecho yo mismo, pero no veo por qué no funcionaría.
Nota Solo tienes que registrar las funciones que quieras usar en tu html como ayudantes de manubrios. Personalmente, tengo todos los míos registrados porque los uso de forma independiente, pero usted no tiene que hacerlo si no prevé la necesidad de usarlos directamente.
Un retroceso a la programación procedimental :)
Comentario más útil
esto parece tener soporte nativo usando algo como:
{{ helper1 (helper2 text) }}