简体   繁体   English

如何使用underscore.js作为模板引擎?

[英]How to use underscore.js as a template engine?

I'm trying to learn about new usages of javascript as a serverside language and as a functional language. 我正在尝试了解javascript作为服务器端语言和函数式语言的新用法。 Few days ago I heard about node.js and express framework. 几天前我听说过node.js和表达框架。 Then I saw about underscore.js as a set of utility functions. 然后我看到underscore.js作为一组实用函数。 I saw this question on stackoverflow . 在stackoverflow上看到了这个问题 It says we can use underscore.js as a template engine. 它说我们可以使用underscore.js作为模板引擎。 anybody know good tutorials about how to use underscore.js for templating, especially for biginners who have less experience with advanced javascript. 任何人都知道有关如何使用underscore.js进行模板化的好教程,特别是对于那些对高级javascript经验较少的biginners。 Thanks 谢谢

Everything you need to know about underscore template is here . 您需要了解的关于下划线模板的所有内容都在这里 Only 3 things to keep in mind: 只需记住3件事:

  1. <% %> - to execute some code <% %> - 执行一些代码
  2. <%= %> - to print some value in template <%= %> - 在模板中打印一些值
  3. <%- %> - to print some values HTML escaped <%- %> - 打印一些HTML转义的值

That's all about it. 这就是它的全部。

Simple example: 简单的例子:

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

then tpl({foo: "blahblah"}) would be rendered to the string <h1>Some text: blahblah</h1> 那么tpl({foo: "blahblah"})将呈现给字符串<h1>Some text: blahblah</h1>

<!-- 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 Thanks @PHearst! JsFiddle谢谢@PHearst!
  • JsFiddle (latest) JsFiddle (最新)
  • JsFiddle List grouped by first letter (complex example w/ images, function calls, sub-templates) fork it! JsFiddle列表按第一个字母(复杂的例子w /图像,函数调用,子模板)分组! have a blast... 尽情狂欢...
  • JsFiddle Demo of XSS hack noted by @tarun_telang below 下面是@tarun_telang注意到的XSS hack的JsFiddle演示
  • JsFiddle One non-standard method to do sub-templates JsFiddle一个非标准方法来做子模板

In it's simplest form you would use it like: 在它最简单的形式,你会使用它:

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

If you're going to be using a template a few times you'll want to compile it so it's faster: 如果你要使用模板几次,你会想要编译它,所以它更快:

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

I personally prefer the Mustache style syntax. 我个人更喜欢Mustache风格的语法。 You can adjust the template token markers to use double curly braces: 您可以调整模板标记标记以使用双花括号:

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

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

The documentation for templating is partial, I watched the source. 模板的文档是部分的,我看了源。

The _.template function has 3 arguments: _.template函数有3个参数:

  1. String text : the template string 字符串文本 :模板字符串
  2. Object data : the evaluation data 对象数据 :评估数据
  3. Object settings : local settings, the _.templateSettings is the global settings object 对象设置 :本地设置, _. trylateSettings是全局设置对象

If no data (or null) given, than a render function will be returned. 如果没有给出数据 (或null),则返回渲染函数。 It has 1 argument: 它有一个参数:

  1. Object data : same as the data above 对象数据 :与上面的数据相同

There are 3 regex patterns and 1 static parameter in the settings: 设置中有3个正则表达式模式和1个静态参数:

  1. RegExp evaluate : "<%code%>" in template string RegExp 评估 :模板字符串中的“<%code%>”
  2. RegExp interpolate : "<%=code%>" in template string RegExp 插值 :模板字符串中的“<%= code%>”
  3. RegExp escape : "<%-code%>" RegExp 转义 :“<% - code%>”
  4. String variable : optional, the name of the data parameter in the template string 字符串变量 :可选,模板字符串中数据参数的名称

The code in an evaluate section will be simply evaluated. 将简单评估评估部分中的代码。 You can add string from this section with the __p+="mystring" command to the evaluated template, but this is not recommended (not part of the templating interface), use the interpolate section instead of that. 您可以使用__p + =“mystring”命令将此部分中的字符串添加到已评估的模板中,但不建议这样做(不是模板界面的一部分),请使用插值部分而不是它。 This type of section is for adding blocks like if or for to the template. 此类型的部分用于向模板添加if或for等块。

The result of the code in the interpolate section will added to the evaluated template. 插值部分中的代码结果将添加到评估的模板中。 If null given back, then empty string will added. 如果返回null,则添加空字符串。

The escape section escapes html with _.escape on the return value of the given code. 转义部分使用_.escape对给定代码的返回值转义html。 So its similar than an _.escape(code) in an interpolate section, but it escapes with \\ the whitespace characters like \\n before it passes the code to the _.escape . 因此其类似比在插值部的_.escape(代码),但它与\\的空白字符等\\逸出ñ它传递代码到_.escape之前。 I don't know why is that important, it's in the code, but it works well with the interpolate and _.escape - which doesn't escape the white-space characters - too. 我不知道为什么这很重要,它在代码中,但它适用于插值_.escape - 它也不会逃避空白字符。

By default the data parameter is passed by a with(data){...} statement, but this kind of evaluating is much slower than the evaluating with named variable. 默认情况下, data参数由with(data){...}语句传递,但这种评估比使用命名变量进行评估要慢得多。 So naming the data with the variable parameter is something good... 因此,使用变量参数命名数据是件好事......

For example: 例如:

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);

results 结果

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"

You can find here more examples how to use the template and override the default settings: http://underscorejs.org/#template 您可以在此处找到有关如何使用模板和覆盖默认设置的更多示例: http//underscorejs.org/#template

By template loading you have many options, but at the end you always have to convert the template into string. 通过模板加载,您有很多选项,但最后您必须将模板转换为字符串。 You can give it as normal string like the example above, or you can load it from a script tag, and use the .html() function of jquery, or you can load it from a separate file with the tpl plugin of require.js . 您可以像上面的示例一样将其作为普通字符串提供,或者您可以从脚本标记加载它,并使用jquery的.html()函数,或者您可以使用require.jstpl插件从单独的文件加载它。

Another option to build the dom tree with laconic instead of templating. 使用简洁而不是模板来构建dom树的另一种选择。

I am giving a very simple example 我给出一个非常简单的例子

1) 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); 

The result would be 结果将是

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

2) This is a template 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>

This is html 这是HTML

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

This is the javascript code which contains json object and putting template into html 这是包含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}));
  });

with express it's so easy. 表达它很容易。 all what you need is to use the consolidate module on node so you need to install it : 您需要的只是在节点上使用合并模块,因此您需要安装它:

npm install consolidate --save

then you should change the default engine to html template by this: 那么你应该将默认引擎更改为html模板:

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

register the underscore template engine for the html extension: 注册html扩展名的下划线模板引擎:

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

it's done ! 完成 !

Now for load for example an template called 'index.html': 现在加载例如名为'index.html'的模板:

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

maybe you will need to install the underscore module. 也许你需要安装下划线模块。

npm install underscore --save

I hope this helped you! 我希望这对你有所帮助!

I wanted to share one more important finding. 我想分享一个更重要的发现。

use of <%= variable => would result in cross-site scripting vulnerability. 使用<%= variable =>会导致跨站点脚本漏洞。 So its more safe to use <%- variable -> instead. 因此,使用<% - variable - >更安全。

We had to replace <%= with <%- to prevent cross-site scripting attacks. 我们不得不将<%=替换为<% - 以防止跨站点脚本攻击。 Not sure, whether this will it have any impact on the performance 不确定,这是否会对性能产生任何影响

Lodash is also the same First write a script as follows: 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>

Now write some simple JS as follows: 现在编写一些简单的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");

Where popoup is a div where you want to generate the table popoup是你想要生成表格的div

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM