Mustache 템플릿에서 후행 쉼표없이 쉼표로 구분 된 목록을 표현하는 우아한 방법이 있습니까?
Mustache 템플릿 라이브러리를 사용하고 있으며 , 예를 들어 후행 쉼표없이 쉼표로 구분 된 목록을 생성하려고합니다.
빨강, 녹색, 파랑
후행 쉼표로 목록을 만드는 것은 구조를 고려할 때 간단합니다.
{
"items": [
{"name": "red"},
{"name": "green"},
{"name": "blue"}
]
}
및 템플릿
{{#items}}{{name}}, {{/items}}
이것은 해결 될 것이다
빨강, 녹색, 파랑,
그러나 후행 쉼표 없이는 케이스를 우아하게 표현할 수 없습니다. 템플릿에 전달하기 전에 항상 코드에서 목록을 생성 할 수 있지만 라이브러리가 템플릿 내 목록의 마지막 항목인지 여부를 감지 할 수 있도록 허용하는 것과 같은 대체 접근 방식을 제공하는지 궁금합니다.
흠, 의심 스럽지만 콧수염 데모 는 first
속성 과 함께 쉼표를 넣을 때를 파악하기 위해 JSON 데이터 내부에 논리가 있어야 함을 거의 보여줍니다 .
따라서 데이터는 다음과 같습니다.
{
"items": [
{"name": "red", "comma": true},
{"name": "green", "comma": true},
{"name": "blue"}
]
}
및 귀하의 템플릿
{{#items}}
{{name}}{{#comma}},{{/comma}}
{{/items}}
우아하지는 않지만 다른 사람들이 언급했듯이 Mustache는 매우 가볍고 그러한 기능을 제공하지 않습니다.
더 나은 방법은 모델을 동적으로 변경하는 것입니다. 예를 들어 JavaScript를 사용하는 경우 :
model['items'][ model['items'].length - 1 ].last = true;
템플릿에서 반전 섹션을 사용하십시오.
{{#items}}
{{name}}{{^last}}, {{/last}}
{{/items}}
쉼표를 렌더링합니다.
CSS를 속이고 사용하십시오.
모델이 다음과 같은 경우 :
{
"items": [
{"name": "red"},
{"name": "green"},
{"name": "blue"}
]
}
그런 다음 템플릿을 만드십시오.
<div id="someContainer">
{{#items}}
<span>{{name}}<span>
{{/items}}
</div>
그리고 약간의 CSS를 추가합니다.
#someContainer span:not(:last-of-type)::after {
content: ", "
}
나는 누군가가 이것이 프레젠테이션에 마크 업을 넣는 나쁜 경우라고 말할 것이라고 생각하지만 그렇게 생각하지 않습니다. 값을 구분하는 쉼표는 기본 데이터를 더 쉽게 해석하기위한 프레젠테이션 결정입니다. 항목의 글꼴 색상을 번갈아 가며 바꾸는 것과 유사합니다.
사용 될 일 경우 jmustache을 , 당신은 특별한 사용할 수 있습니다 -first
또는 -last
변수를 :
{{#items}}{{name}}{{^-last}}, {{/-last}}{{/items}}
Mustache가이를위한 우아한 방법을 제공하는지 여부에 대한 질문에 대한 답을 얻었지만이를 수행하는 가장 우아한 방법은 모델을 변경하는 대신 CSS를 사용하는 것일 수 있습니다.
주형:
<ul class="csl">{{#items}}<li>{{name}}</li>{{/items}}</ul>
CSS :
.csl li
{
display: inline;
}
.csl li:before
{
content: ", "
}
.csl li:first-child:before
{
content: ""
}
이것은 IE8 + 및 기타 최신 브라우저에서 작동합니다.
<ul>
또는 외부에 알 수없는 수의 항목을 나열하고 싶은 상황을 많이 생각할 수 없지만 <ol>
다음과 같이 할 수 있습니다.
<p>
Comma separated list, in sentence form;
{{#each test}}{{#if @index}}, {{/if}}{{.}}{{/each}};
sentence continued.
</p>
… 생산 :
Command separated list, in sentence form; asdf1, asdf2, asdf3; sentence continued.
This is Handlebars, mind you. @index
will work if test
is an Array.
There is not a built-in way to do this in Mustache. You have to alter your model to support it.
One way to implement this in the template is to use the inverted selection hat {{^last}} {{/last}}
tag. It will only omit text for the last item in the list.
{{#items}}
{{name}}{{^last}}, {{/last}}
{{/items}}
Or you can add a delimiter string as ", "
to the object, or ideally the base class if you're using a language that has inheritance, then set "delimiter" to an empty string " "
for the last element like this:
{{#items}}
{{name}}{{delimiter}}
{{/items}}
As the question is:
is there an elegant way of expressing a comma separated list without the trailing comma?
Then changing the data - when being the last item is already implicit by it being the final item in the array - isn't elegant.
Any mustache templating language that has array indices can do this properly,. ie. without adding anything to the data. This includes handlebars, ractive.js, and other popular mustache implementations.
{{# names:index}}
{{ . }}{{ #if index < names.length - 1 }}, {{ /if }}
{{ / }}
For JSON data I suggest:
Mustache.render(template, settings).replace(/,(?=\s*[}\]])/mig,'');
The regexp will remove any ,
left hanging after the last properties.
This will also remove ,
from string values contining ", }" or ", ]" so make sure you know what data will be put into your JSON
As Mustache stands on Handlebars, why not use a @data variable? I found this the cleanest option:
{{#if @last}}, {{/if}}
More info: http://handlebarsjs.com/reference.html#data
Simplest way I found was to render list and then remove last char.
- Render mustache.
- Remove any white space before and after string.
Then remove last character
let renderedData = Mustache Render(dataToRender, data); renderedData=(renderedData.trim()).substring(0, renderedData.length-1)
Interesting. I know it's kind of lazy but I usually get around this by templating in the value assignment rather than trying to comma delimitate the values.
var global.items = {};
{{#items}}
global.items.{{item_name}} = {{item_value}};
{{/items}}
I tend to think this is a task well suited to CSS (as answered by others). However, assuming you are attempting to do something like produce a CSV file, you would not have HTML and CSS available to you. Also, if you are considering modifying data to do this anyway, this may be a tidier way to do it:
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);
If you are using java, you can use the following :
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());
'developer tip' 카테고리의 다른 글
함수 매개 변수의 "this" (0) | 2020.10.11 |
---|---|
객체를 사전에 매핑하거나 그 반대로 매핑 (0) | 2020.10.11 |
모든 EditText에 일관된 스타일 설정 (예 :) (0) | 2020.10.11 |
Python은 str.format을 사용하여 선행 0을 추가합니다. (0) | 2020.10.11 |
Perl : 문자열 선행 및 후행 공백을 제거하는 기능 (0) | 2020.10.11 |