underscore.jsをテンプレートエンジンとして使用する方法


262

サーバーサイド言語および関数型言語としてのJavaScriptの新しい使用法について学習しようとしています。数日前、node.jsとExpressフレームワークについて聞いたことがあります。次に、underscore.jsをユーティリティ関数のセットとして見ました。私はこの問題をstackoverflowで 見ました。これは、テンプレートエンジンとしてunderscore.jsを使用できることを示しています。特に高度なJavaScriptの経験が少ない初心者のために、テンプレートにunderscore.jsを使用する方法についてのチュートリアルは、誰でも知っています。ありがとう


12
「ルーク」の弁護では、少なくとも5月に改良版のマニュアルに高度な使用法がありませんでした
シャニマル

あなたの質問にも役立つ同様の質問に答えました。stackoverflow.com/questions/28136101/retrieve-column-in-parse/...
jeffdill2

回答:


475

アンダースコアテンプレートについて知っておくべきことはすべてここにあります。覚えておくべきことは3つだけです。

  1. <% %> -いくつかのコードを実行する
  2. <%= %> -テンプレートに値を印刷する
  3. <%- %> -HTMLエスケープされた一部の値を出力する

これですべてです。

簡単な例:

var tpl = _.template("<h1>Some text: <%= foo %></h1>");

次にtpl({foo: "blahblah"})、文字列にレンダリングされます<h1>Some text: blahblah</h1>


55
誰もが、それがダウン票これでなぜ私は理解していないプロジェクトのホームページ上の指示に標準的な答えやポイントを、それは古典的な「ティーチ魚の男」です。
Jon z

1
私は彼らが反対票を投じると、彼らが提供するドキュメントがそれらの特異な例を超えて<%と<%=を混合する方法、および<%=からprint()に切り替えるとそのパターンがどのように変化するかについてほとんど提供しません。また、「補間」を使用するときは、おそらくもう少し説明を付けてシーンを作成するいくつかの奇妙な動作があります。これも提供されていません。私は同意しますが、その愚かなことは反対票を投じます。
QueueHammer

8
3. <%-%>-一部の値をHTMLをエスケープして印刷する
LeeGee

13
私は反対票を投じなかったが、あなたの答えは(リンクを提供することを除いて)テンプレートエンジンとしてunderscore.jsを使用する方法を説明するために何もしません。あなたの答えはおそらくすでにそれを手に入れている人たちのための簡単な「チートシート」を提供しますが、それ自体では質問への答えではありません。私はそれがそれと同じくらい多くの賛成票を持っていることに驚いています。
Zach Lysobey 2013

1
-1、ドキュメントは多くの点で不十分です。ドキュメントを調べた後、ユーザーがここに来たことはほぼ確実です。悪い答え。
Matt Parkins、2014年

198
<!-- Install jQuery and underscore -->

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore-min.js"></script>

<!-- Create your template -->
<script type="foo/bar" id='usageList'>
<table cellspacing='0' cellpadding='0' border='1' >
    <thead>
      <tr>
        <th>Id</th>
        <th>Name</th>
      </tr>
    </thead>
    <tbody>
      <%
        // repeat items 
        _.each(items,function(item,key,list){
          // create variables
          var f = item.name.split("").shift().toLowerCase();
      %>
        <tr>
          <!-- use variables -->
          <td><%= key %></td>
          <td class="<%= f %>">
            <!-- use %- to inject un-sanitized user input (see 'Demo of XSS hack') -->
            <h3><%- item.name %></h3>
            <p><%- item.interests %></p>
          </td>
        </tr>
      <%
        });
      %>
    </tbody>
  </table>
</script>

<!-- Create your target -->

<div id="target"></div>

<!-- Write some code to fetch the data and apply template -->

<script type="text/javascript">
  var items = [
    {name:"Alexander", interests:"creating large empires"},
    {name:"Edward", interests:"ha.ckers.org <\nBGSOUND SRC=\"javascript:alert('XSS');\">"},
    {name:"..."},
    {name:"Yolando", interests:"working out"},
    {name:"Zachary", interests:"picking flowers for Angela"}
  ];
  var template = $("#usageList").html();
  $("#target").html(_.template(template,{items:items}));
</script>
  • JsFiddleありがとう@PHearst!
  • JsFiddle(最新)
  • 最初の文字でグループ化されたJsFiddleリスト(画像、関数呼び出し、サブテンプレートを含む複雑な例)はフォークします!爆風を持っている...
  • 以下の@tarun_telangで言及されているXSSハックのJsFiddleデモ
  • JsFiddleサブテンプレートを実行するための非標準的な方法

17
例の中で「text / html」スクリプトタグを明示的に使用していただきありがとうございます。私はunderscore.jsを初めて使用し、不幸にもドキュメントを読み間違えました。templateStringを常にインラインで記述する必要がないことを知っておくと便利です。
aschyiel

テンプレートは実際にはtext/htmlそうではありませんのでtype="text/html"、嘘は問題を引き起こす可能性があります。のような正確なタイプを使用することをお勧めしますtext/x-underscore
muが短すぎる

6
ミュー、それは問題ではないことを指摘するのは良いことだと思います。それに直面しよう、あなたがそこに置いたものはすべて嘘です。私はlodash、lolを使用しているため、text / x-underscoreはより大きな嘘です:)最後のJsFiddleで追加type="foo/bar"したのは、ブラウザ/サーバーがそれを認識しない限り、問題ではないことをみんなに知らせて、試したいからですそれで何かをするために。htmlはスクリプトの一種ではないので、text / html(John Resigが使用しています)でかなり安全だと思いますfoo / barも機能します:)
Shanimal 2013

4
人々はいつも私に反対します、私はそれを個人的に取らないように最善を尽くします(それが個人的なものであっても:)。私はマイナーなだらしの意図しない副作用に何度も何度も火傷を負っていたので、私の癖は厳格さの問題です。MIMEタイプの仕様では、実際に*/x-*は「作り上げ」の使用のためにタイプが予約されています。text/underscore公式レジストリにタイプはないと思いますtext/x-underscore。私は偏執的で、彼らは本当に私を捕まえているので使用します。
muが短すぎる

1
ブラウザが不正な
MIMEタイプで

94

最も単純な形式では、次のように使用します。

var html = _.template('<li><%= name %></li>', { name: 'John Smith' });
//html is now '<li>John Smith</li>'   

テンプレートを数回使用する場合は、それをコンパイルして高速にする必要があります。

var template = _.template('<li><%= name %></li>');

var html = [];
for (var key in names) {
    html += template({ name: names[i] });
}

console.log(html.join('')); //Outputs a string of <li> items

私は口ひげスタイルの構文を個人的に好みます。テンプレートトークンマーカーを調整して、二重中括弧を使用できます。

_.templateSettings.interpolate = /\{\{(.+?)\}\}/g;

var template = _.template('<li>{{ name }}</li>');

Moustache補間のヒントは、ejsを使用してレンダリングされたexpress3ビューの使用中に私を助けました。ありがとう!
micrub 2014年

ビューからテンプレートを使用するには、ページマークアップに以下を含めることができます:<script type = "text / template" id = "my-template"> <div> <%-name%> </ div> </ script >次に、JSで次の操作を行います。var html = _.template($( '#my-template')。html()、{name: "John Smith"});
Gaurav Gupta、2014

2
@evilcelery- interpolateヒントは機能しませんでしたが、これは機能しました:_.templateSettings = { interpolate: /\{\{\=(.+?)\}\}/g, escape: /\{\{\-(.+?)\}\}/g, evaluate: /\{\{(.+?)\}\}/g };
vsync

28

テンプレートのドキュメントは部分的です。ソースを見てみました。

_.templateの機能は3つの引数があります。

  1. 文字列テキスト:テンプレート文字列
  2. オブジェクトデータ:評価データ
  3. オブジェクト設定:ローカル設定、_。templateSettingsはグローバル設定オブジェクトです

データがない場合(またはnullの場合)、レンダリング関数が返されます。引数は1つです。

  1. オブジェクトデータ:上記のデータと同じ

設定には3つの正規表現パターンと1つの静的パラメーターがあります。

  1. RegExpの評価:テンプレート文字列の "<%code%>"
  2. RegExp 補間:テンプレート文字列の "<%= code%>"
  3. RegExp エスケープ: "<%-code%>"
  4. 文字列変数:オプション、テンプレート文字列内のデータパラメータの名前

評価セクションのコードは単純に評価されます。__p + = "mystring"コマンドを使用してこのセクションの文字列を評価済みテンプレートに追加できますが、これはお勧めできません(テンプレートインターフェイスの一部ではありません)。代わりに補間セクションを使用してください。このタイプのセクションは、ifまたはforのようなブロックをテンプレートに追加するためのものです。

補間セクションのコードの結果は、評価されたテンプレートに追加されます。nullが返された場合、空の文字列が追加されます。

エスケープのセクションエスケープHTML _.escape与えられたコードの戻り値に。よりその類似したので_.escape(コード)補間セクションが、それはしてエスケープ\などの空白文字のn \それがコードを渡す前に_.escape。なぜそれが重要なのかはわかりませんが、コード内にありますが、空白文字をエスケープしないinterpolateおよび_.escapeでもうまく機能します。

デフォルトでは、データパラメータはwith(data){...}ステートメントによって渡されますが、この種の評価は、名前付き変数による評価よりもはるかに遅くなります。命名だから、データを変数パラメーターを使用は良いことです...

例えば:

var html = _.template(
    "<pre>The \"<% __p+=_.escape(o.text) %>\" is the same<br />" +
        "as the  \"<%= _.escape(o.text) %>\" and the same<br />" +
        "as the \"<%- o.text %>\"</pre>",
    {
        text: "<b>some text</b> and \n it's a line break"
    },
    {
        variable: "o"
    }
);

$("body").html(html);

結果

The "<b>some text</b> and 
 it's a line break" is the same
as the "<b>some text</b> and 
 it's a line break" and the same
as the "<b>some text</b> and 
 it's a line break"

テンプレートの使用方法とデフォルト設定を上書きする方法の例については、こちらをご覧ください:http : //underscorejs.org/#template

テンプレートの読み込みには多くのオプションがありますが、最終的には常にテンプレートを文字列に変換する必要があります。上記の例のように通常の文字列として指定するか、スクリプトタグから読み込んでjqueryの.html()関数を使用するか、require.jsのtplプラグイン使用して別のファイルから読み込むことができます。

テンプレートの代わりに簡潔な domツリーを構築する別のオプション。


21

私は非常に簡単な例を挙げています

1)

var data = {site:"mysite",name:"john",age:25};
var template = "Welcome you are at <%=site %>.This has been created by <%=name %> whose age is <%=age%>";
var parsedTemplate = _.template(template,data);
console.log(parsedTemplate); 

結果は

Welcome you are at mysite.This has been created by john whose age is 25.

2)これはテンプレートです

   <script type="text/template" id="template_1">
       <% _.each(items,function(item,key,arr) { %>
          <li>
             <span><%= key %></span>
             <span><%= item.name %></span>
             <span><%= item.type %></span>
           </li>
       <% }); %>
   </script>

これはhtmlです

<div>
  <ul id="list_2"></ul>
</div>

これは、jsonオブジェクトを含み、テンプレートをhtmlに配置するjavascriptコードです

   var items = [
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       },
       {
          name:"name1",
          type:"type1"
       } 
   ];
  $(document).ready(function(){
      var template = $("#template_1").html();
      $("#list_2").html(_.template(template,{items:items}));
  });


14

エクスプレスを使用すると、とても簡単です。必要なのは、ノードで統合モジュールを使用することだけなので、インストールする必要があります。

npm install consolidate --save

次に、デフォルトのエンジンをhtmlテンプレートに変更する必要があります。

app.set('view engine', 'html');

下線テンプレートエンジンをhtml拡張に登録します。

app.engine('html', require('consolidate').underscore);

終わった !

次に、たとえば「index.html」というテンプレートをロードします。

res.render('index', { title : 'my first page'});

下線モジュールをインストールする必要があるかもしれません。

npm install underscore --save

これがお役に立てば幸いです。


12

私はもう1つの重要な発見を共有したいと思いました。

<%= variable =>を使用すると、クロスサイトスクリプティングの脆弱性が発生します。したがって、代わりに<%-変数->を使用する方が安全です。

クロスサイトスクリプティング攻撃を防ぐために、<%=を<%-に置き換える必要がありました。確かに、これがパフォーマンスに影響を与えるかどうか


2
+1 XSSに関するメモを例に追加しました。これは、サニタイズされていないユーザー情報をWebページに挿入することに関して非常に良い点です。テンプレートエンジンまたは$ .html()のいずれかを使用します。
Shanimal 2014年

1

Lodashも同じです最初に次のようにスクリプトを記述します。

<script type="text/template" id="genTable">
<table cellspacing='0' cellpadding='0' border='1'>
        <tr>
            <% for(var prop in users[0]){%>
            <th><%= prop %> </th>
            <% }%>
        </tr>
        <%_.forEach(users, function(user) { %>
            <tr>
                 <% for(var prop in user){%>
                    <td><%= user[prop] %> </td>
                <% }%>

            </tr>
        <%})%>
</table>

次に、簡単なJSを次のように記述します。

var arrOfObjects = [];
for (var s = 0; s < 10; s++) {
    var simpleObject = {};
    simpleObject.Name = "Name_" + s;
    simpleObject.Address = "Address_" + s;
    arrOfObjects[s] = simpleObject;
}
var theObject = { 'users': arrOfObjects }
var compiled = _.template($("#genTable").text());
var sigma = compiled({ 'users': myArr });

$(sigma).appendTo("#popup");

ここでpopoupは、テーブルを生成するdivです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.