web-dev-qa-db-ja.com

Moustacheテンプレートでは、末尾のコンマなしでコンマ区切りリストを表現するエレガントな方法がありますか?

Mustache templating library を使用しており、末尾のコンマのないコンマ区切りリストを生成しようとしています。

赤、緑、青

構造を考えると、末尾のコンマでリストを作成するのは簡単です

{
  "items": [
    {"name": "red"},
    {"name": "green"},
    {"name": "blue"}
  ]
}

そしてテンプレート

{{#items}}{{name}}, {{/items}}

これはに解決されます

赤、緑、青、

ただし、末尾のコンマなしでケースを表現するエレガントな方法は見当たりません。リストをテンプレートに渡す前にコードでいつでも生成できますが、ライブラリがテンプレート内のリストの最後のアイテムであるかどうかを検出できるようにするなどの代替アプローチを提供するかどうか疑問に思っていました。

77
John Kane

Hrm、疑わしい、 mustache demo は、firstプロパティで、コンマをいつ挿入するかを判断するためにJSONデータ内にロジックが必要であることを示しています。

したがって、データは次のようになります。

{
  "items": [
    {"name": "red", "comma": true},
    {"name": "green", "comma": true},
    {"name": "blue"}
  ]
}

そしてあなたのテンプレート

{{#items}}
    {{name}}{{#comma}},{{/comma}}
{{/items}}

私はそれがエレガントではないことを知っていますが、 他の人が述べたように Moustacheは非常に軽量で、そのような機能を提供しません。

40
Luca Matteis

モデルを動的に変更する方が良いと思います。たとえば、JavaScriptを使用している場合:

model['items'][ model['items'].length - 1 ].last = true;

テンプレートで、逆セクションを使用します。

{{#items}}
    {{name}}{{^last}}, {{/last}}
{{/items}}

そのコンマをレンダリングします。

88
Clyde

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: ", "    
}

プレゼンテーションにマークアップを入れるのは悪いケースだと誰かが言うだろうと思うが、そうではないと思う。値をコンマで区切ることは、基礎となるデータの解釈を容易にするための表示の決定です。エントリのフォントの色を変えることに似ています。

38
Jared

jmustache を使用している場合は、特別な-firstまたは-last変数:

{{#items}}{{name}}{{^-last}}, {{/-last}}{{/items}}
24
dbort

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 +およびその他の最新のブラウザーで機能します。

6
David Hammond

Moustacheにこれを行う組み込みの方法はありません。モデルを変更してサポートする必要があります。

これをテンプレートに実装する1つの方法は、反転選択帽子{{^last}} {{/last}}タグを使用することです。リスト内のlast項目のテキストのみが省略されます。

{{#items}}
    {{name}}{{^last}}, {{/last}}
{{/items}}

または、オブジェクトに", "として区切り文字列を追加できます。または、継承を持つ言語を使用している場合は理想的には基本クラスに追加し、最後の空文字列" "に「区切り文字」を設定できますこのような要素:

{{#items}}
    {{name}}{{delimiter}}
{{/items}}
5
cosbor11

<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.

これがハンドルバーです。 testが配列の場合、@indexは機能します。

5
Steven Vachon

問題は次のとおりです。

末尾のコンマなしでコンマ区切りリストを表現するエレガントな方法はありますか?

次に、データを変更する-最後のアイテムである場合、配列の最後のアイテムであることが既に暗黙的である場合-はエレガントではありません。

配列インデックスを持つ口ひげテンプレート言語は、これを適切に行うことができます。すなわち。 データに何も追加せずに。これには、ハンドルバー、ractive.js、およびその他の一般的な口ひげの実装が含まれます。

{{# names:index}}
    {{ . }}{{ #if index < names.length - 1 }}, {{ /if }}
{{ / }}
2
mikemaccana

MustacheはHandlebarsの上に立つので、@ data変数を使用してみませんか?これが最もクリーンなオプションであることがわかりました。

{{#if @last}}, {{/if}}

詳細: http://handlebarsjs.com/reference.html#data

1
Roberto14

JSONデータの場合:

Mustache.render(template, settings).replace(/,(?=\s*[}\]])/mig,'');

正規表現は、最後のプロパティの後にぶら下がっている,を削除します。

これにより、「[}]」または「、]」が続く文字列値から,も削除されるため、JSONに入力されるデータを確認してください。

1
mathiasrw

面白い。私はそれがちょっと怠けていることを知っていますが、私は通常、値をコンマで区切ろうとするのではなく、値の割り当てをテンプレート化することでこれを回避します。

var global.items = {};
{{#items}}
    global.items.{{item_name}} = {{item_value}};
{{/items}}
0
Iwnnay

Javaを使用している場合は、次を使用できます。

https://github.com/spullara/mustache.Java/blob/master/compiler/src/test/Java/com/github/mustachejava/util/DecoratedCollectionTest.Java

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());
0
王子1986

私が見つけた最も簡単な方法は、リストをレンダリングしてから最後の文字を削除することでした。

  1. 口ひげをレンダリングします。
  2. 文字列の前後の空白を削除します。
  3. 次に、最後の文字を削除します

    let renderData = Moustache Render(dataToRender、data); renderingData =(renderedData.trim())。substring(0、renderingData.length-1)

私はこれがCSSに非常に適したタスクだと思う傾向があります(他の人が答えたように)。ただし、CSVファイルを作成するなどの操作を行おうとすると、HTMLとCSSを使用できなくなります。また、とにかくこれを行うためにデータを変更することを検討している場合、これはそれを行うためのよりきれいな方法かもしれません:

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);
0
Jefferey Cave