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

kno*_*umi 260 javascript functional-programming template-engine node.js underscore.js

我正在尝试了解javascript作为服务器端语言和函数式语言的新用法.几天前我听说过node.js和表达框架.然后我看到underscore.js作为一组实用函数.我在stackoverflow上看到了这个问题 .它说我们可以使用underscore.js作为模板引擎.任何人都知道有关如何使用underscore.js进行模板化的好教程,特别是对于那些对高级javascript经验较少的biginners.谢谢

SET*_*SET 468

您需要了解的关于下划线模板的所有内容都在这里.只需记住3件事:

  1. <% %> - 执行一些代码
  2. <%= %> - 在模板中打印一些值
  3. <%- %> - 打印一些HTML转义的值

这就是它的全部.

简单的例子:

var tpl = _.template("<h1>Some text: <%= foo %></h1>");
Run Code Online (Sandbox Code Playgroud)

然后tpl({foo: "blahblah"})将呈现给字符串<h1>Some text: blahblah</h1>

  • 我不明白为什么有人会对此进行投票,这是_the_规范的答案,并指出项目主页上的说明,这是经典的"教人钓鱼". (55认同)
  • 我没有downvote,但你的答案没有做任何事情(除了提供一个链接)来解释如何使用underscore.js作为模板引擎.你的答案提供了一个快速的"备忘单",也许对那些已经得到它的人来说,但就其本身而言,它不是问题的答案.我很惊讶它有尽可能多的赞成. (12认同)
  • 3. <% - %> - 使用HTML转义打印某些值 (8认同)

Sha*_*mal 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>
Run Code Online (Sandbox Code Playgroud)
  • JsFiddle谢谢@PHearst!
  • JsFiddle(最新)
  • JsFiddle列表按第一个字母(复杂的例子w /图像,函数调用,子模板)分组!尽情狂欢...
  • 下面是@tarun_telang注意到的XSS hack的JsFiddle演示
  • JsFiddle一个非标准方法来做子模板

  • 感谢您在示例中明确使用"text/html"脚本标记; 我是新的下划线.我和我不愉快地误读了文档 - 很高兴知道templateString并不总是必须内联编写. (17认同)
  • mu,我认为很好地指出它并不重要.让我们面对现实,你放在那里的任何东西都是谎言.text/x-underscore是一个更大的谎言,因为我使用lodash,lol :)在最后的JsFiddle我添加了`type ="foo/bar"`因为我希望每个人都知道只要浏览器就没关系/ server无法识别它并试图用它做一些事情.由于html不是一种脚本,我觉得使用text/html是相当安全的(John Resig使用它)foo/bar也适用:) (6认同)
  • 人们总是不同意我的意见,我尽力不亲自接受(即使它是个人的:).我被一遍又一遍的轻微邋iness的意外副作用所灼伤,所以我的习惯是在严格的一面犯错.MIME类型规范实际上为"组合"用途保留了`*/x-*`类型,我认为官方注册表中没有"text/underscore"类型,所以我使用`text/x-underscore`因为我很偏执,他们真的很想得到我. (4认同)

evi*_*ery 94

在它最简单的形式,你会使用它:

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

如果你要使用模板几次,你会想要编译它,所以它更快:

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
Run Code Online (Sandbox Code Playgroud)

我个人更喜欢Mustache风格的语法.您可以调整模板标记标记以使用双花括号:

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

var template = _.template('<li>{{ name }}</li>');
Run Code Online (Sandbox Code Playgroud)

  • @evilcelery - 你的'interpolate`提示不起作用,但是这样做了:`_.templateSettings = {interpolate:/\{\{\=(.+?)\}}}/logo,escape:/\{\ {\ - (.+?)\} \}/g,评价:/\ {.{(+.+?)}}}}}}} (2认同)

inf*_*rno 28

模板的文档是部分的,我看了源.

_.template函数有3个参数:

  1. 字符串文本:模板字符串
  2. 对象数据:评估数据
  3. 对象设置:本地设置,_. trylateSettings是全局设置对象

如果没有给出数据(或null),则返回渲染函数.它有一个参数:

  1. 对象数据:与上面的数据相同

设置中有3个正则表达式模式和1个静态参数:

  1. RegExp 评估:模板字符串中的"<%code%>"
  2. RegExp 插值:模板字符串中的"<%= code%>"
  3. RegExp 转义:"<% - code%>"
  4. 字符串变量:可选,模板字符串中数据参数的名称

将简单评估评估部分中的代码.您可以使用__p + ="mystring"命令将此部分中的字符串添加到已评估的模板中,但不建议这样做(不是模板界面的一部分),请使用插值部分而不是它.此类型的部分用于向模板添加if或for等块.

插值部分中的代码结果将添加到评估的模板中.如果返回null,则添加空字符串.

逃逸部分逃脱HTML与_.escape在给定的代码的返回值.因此其类似比_.escape(代码)中的内插部分,但它与逃逸\的空白字符等\n它传递的代码到前_.escape.我不知道为什么这很重要,它在代码中,但它适用于插值_.escape - 它也不会逃避空白字符.

默认情况下,data参数由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);
Run Code Online (Sandbox Code Playgroud)

结果

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"
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到有关如何使用模板和覆盖默认设置的更多示例:http: //underscorejs.org/#template

通过模板加载,您有很多选项,但最后您必须将模板转换为字符串.你可以把它当作普通的字符串就像上面的例子中,也可以从一个脚本标签加载它,使用的.html()的jQuery的功能,也可以从一个单独的文件与加载它TPL插件require.js.

使用简洁而不是模板来构建dom树的另一种选择.


小智 22

我给出一个非常简单的例子

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); 
Run Code Online (Sandbox Code Playgroud)

结果将是

Welcome you are at mysite.This has been created by john whose age is 25.
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

这是HTML

<div>
  <ul id="list_2"></ul>
</div>
Run Code Online (Sandbox Code Playgroud)

这是包含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}));
  });
Run Code Online (Sandbox Code Playgroud)


小智 14

表达它很容易.您需要的只是在节点上使用合并模块,因此您需要安装它:

npm install consolidate --save
Run Code Online (Sandbox Code Playgroud)

那么你应该将默认引擎更改为html模板:

app.set('view engine', 'html');
Run Code Online (Sandbox Code Playgroud)

注册html扩展名的下划线模板引擎:

app.engine('html', require('consolidate').underscore);
Run Code Online (Sandbox Code Playgroud)

完成 !

现在加载例如名为'index.html'的模板:

res.render('index', { title : 'my first page'});
Run Code Online (Sandbox Code Playgroud)

也许你需要安装下划线模块.

npm install underscore --save
Run Code Online (Sandbox Code Playgroud)

我希望这对你有所帮助!


Tar*_*run 12

我想分享一个更重要的发现.

使用<%= variable =>会导致跨站点脚本漏洞.因此,使用<% - variable - >更安全.

我们不得不将<%=替换为<% - 以防止跨站点脚本攻击.不确定,这是否会对性能产生任何影响

  • +1我在我的例子中添加了关于XSS的注释.关于将未经过处理的用户信息注入网页,这是一个非常好的观点.通过模板引擎甚至是$ .html(). (2认同)