moustache - En Mustache, la creación de plantillas ¿existe una forma elegante de expresar una lista separada por comas sin la coma final?
mustache styles (13)
Estoy usando la biblioteca de plantillas de Moustache y tratando de generar una lista separada por comas sin una coma al final, por ejemplo
rojo verde azul
Crear una lista con la coma final es sencillo, dada la estructura
{
"items": [
{"name": "red"},
{"name": "green"},
{"name": "blue"}
]
}
y la plantilla
{{#items}}{{name}}, {{/items}}
esto resolverá
rojo verde azul,
Sin embargo, no puedo ver una forma elegante de expresar el caso sin la coma final. Siempre puedo generar la lista en código antes de pasarla a la plantilla, pero me pregunto si la biblioteca ofrece un enfoque alternativo, como permitirle detectar si es el último elemento de una lista dentro de la plantilla.
Como Moustache se encuentra en los manubrios, ¿por qué no utilizar una variable @data? Encontré esta la opción más limpia:
{{#if @last}}, {{/if}}
Más información: http://handlebarsjs.com/reference.html#data
Como la pregunta es:
¿Hay una manera elegante de expresar una lista separada por comas sin la coma final?
Luego, cambiar los datos, cuando el último elemento ya está implícito porque es el último elemento de la matriz, no es elegante.
Cualquier lenguaje de plantillas de bigote que tenga índices de matriz puede hacer esto correctamente. es decir. sin agregar nada a los datos . Esto incluye manubrios, ractive.js y otras implementaciones populares de bigote.
{{# names:index}}
{{ . }}{{ #if index < names.length - 1 }}, {{ /if }}
{{ / }}
Creo que una mejor manera es cambiar el modelo dinámicamente. Por ejemplo, si está usando JavaScript:
model[''items''][ model[''items''].length - 1 ].last = true;
y en su plantilla, use la sección invertida:
{{#items}}
{{name}}{{^last}}, {{/last}}
{{/items}}
para renderizar esa coma
Hrm, dudoso, la demostración del bigote casi te muestra, con la first
propiedad, que tienes que tener la lógica dentro de los datos JSON para averiguar cuándo poner la coma.
Entonces, sus datos se verían así:
{
"items": [
{"name": "red", "comma": true},
{"name": "green", "comma": true},
{"name": "blue"}
]
}
y tu plantilla
{{#items}}
{{name}}{{#comma}},{{/comma}}
{{/items}}
Sé que no es elegante, pero como otros lo mencionan, Moustache es muy liviano y no ofrece esas características.
Interesante. Sé que es un poco vago, pero normalmente lo soluciono al crear plantillas en la asignación de valores en lugar de intentar delimitar en coma los valores.
var global.items = {};
{{#items}}
global.items.{{item_name}} = {{item_value}};
{{/items}}
No hay una forma incorporada de hacer esto en Moustache. Tienes que modificar tu modelo para que sea compatible.
Una forma de implementar esto en la plantilla es usar la etiqueta de selección invertida {{^last}} {{/last}}
. Solo omitirá el texto del último elemento de la lista.
{{#items}}
{{name}}{{^last}}, {{/last}}
{{/items}}
O puede agregar una cadena delimitadora como ", "
al objeto, o idealmente la clase base si está usando un lenguaje que tiene herencia, luego configure "delimitador" en una cadena vacía " "
para el último elemento como este:
{{#items}}
{{name}}{{delimiter}}
{{/items}}
No puedo pensar en muchas situaciones en las que te gustaría enumerar una cantidad desconocida de elementos fuera de un <ul>
o <ol>
, pero así es como lo harías:
<p>
Comma separated list, in sentence form;
{{#each test}}{{#if @index}}, {{/if}}{{.}}{{/each}};
sentence continued.
</p>
…Producirá:
Command separated list, in sentence form; asdf1, asdf2, asdf3; sentence continued.
Esto es Manubrios, fíjate. @index
funcionará si la test
es una matriz.
Para datos JSON sugiero:
Mustache.render(template, settings).replace(/,(?=/s*[}/]])/mig,'''');
La expresión regular eliminará cualquier ,
queda colgando después de las últimas propiedades.
Esto también se eliminará de los valores de cadena que continúen ",}" o ",]", así que asegúrese de saber qué datos se incluirán en su JSON.
Se ha respondido a la pregunta de si Moustache ofrece una forma elegante de hacerlo, pero se me ocurrió que la forma más elegante de hacerlo puede ser utilizar CSS en lugar de cambiar el modelo.
Modelo:
<ul class="csl">{{#items}}<li>{{name}}</li>{{/items}}</ul>
CSS:
.csl li
{
display: inline;
}
.csl li:before
{
content: ", "
}
.csl li:first-child:before
{
content: ""
}
Esto funciona en IE8 + y otros navegadores modernos.
Si está usando jmustache , puede usar las variables especiales -last
o -last
:
{{#items}}{{name}}{{^-last}}, {{/-last}}{{/items}}
Si está utilizando Java, puede usar lo siguiente:
MustacheFactory mf = new DefaultMustacheFactory();
Mustache test = mf.compile(new StringReader("{{#test}}{{#first}}[{{/first}}{{^first}}, {{/first}}/"{{value}}/"{{#last}}]{{/last}}{{/test}}"), "test");
StringWriter sw = new StringWriter();
test.execute(sw, new Object() {
Collection test = new DecoratedCollection(Arrays.asList("one", "two", "three"));
}).flush();
System.out.println(sw.toString());
Tiendo a pensar que esta es una tarea adecuada para CSS (como respondieron otros). Sin embargo, suponiendo que está intentando hacer algo como producir un archivo CSV, no tendría HTML ni CSS disponibles para usted. Además, si está considerando modificar los datos para hacer esto de todos modos, esta puede ser una forma más ordenada de hacerlo:
var data = {
"items": [
{"name": "red"},
{"name": "green"},
{"name": "blue"}
]
};
// clone the original data.
// Not strictly necessary, but sometimes its
// useful to preserve the original object
var model = JSON.parse(JSON.stringify(data));
// extract the values into an array and join
// the array with commas as the delimiter
model.items = Object.values(model.items).join('','');
var html = Mustache.render("{{items}}", model);
Trucos y uso de CSS.
Si su modelo es:
{
"items": [
{"name": "red"},
{"name": "green"},
{"name": "blue"}
]
}
luego haz tu plantilla
<div id="someContainer">
{{#items}}
<span>{{name}}<span>
{{/items}}
</div>
y agrega un poco de CSS
#someContainer span:not(:last-of-type)::after {
content: ", "
}
Supongo que alguien dirá que este es un mal caso para poner el marcado en la presentación, pero no creo que sea así. Los valores de separación de coma son una decisión de presentación para facilitar la interpretación de los datos subyacentes. Es similar a alternar el color de fuente en las entradas.