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

我正在学习javascript作为服务器端语言和函数式语言的新用法。前几天我听说了node.js和express framework。然后我看到了underscore.js作为一组实用函数。我在stackoverflow上看到这个问题 < / >。它说我们可以使用underscore.js作为模板引擎。有人知道关于如何使用underscore.js来做模板的教程吗,特别是对于那些对高级javascript缺乏经验的大程序员。由于< / p >

237287 次浏览

你需要知道的关于下划线模板的一切都是在这里。只需要记住3件事:

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

就是这样。

简单的例子:

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

那么tpl({foo: "blahblah"})将被呈现为字符串<h1>Some text: blahblah</h1>

最简单的形式是这样的:

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

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

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


var template = _.template('<li>\{\{ name }}</li>');
<!-- 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>
  • 谢谢@ phhearst !
  • JsFiddle(最新)
  • JsFiddle列表按第一个字母分组(复杂的例子w/图像,函数调用,子模板)fork !玩得开心点……
  • @tarun_telang注意到下面XSS黑客的演示
  • 一种做子模板的非标准方法

该文档用于模板的部分,我看了源代码。

_.template函数有3个参数:

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

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

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

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

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

评估节中的代码将被简单地求值。你可以使用__p + = "就是"命令将此部分的字符串添加到被评估的模板中,但不建议这样做(不是模板接口的一部分),使用interpolate部分代替它。这种类型的section用于向模板中添加if或for之类的块。

插入部分中代码的结果将被添加到已计算的模板中。如果返回null,则添加空字符串。

逃避节在给定代码的返回值上使用_.escape转义html。因此它类似于插入节中的_.escape(代码),但在将代码传递给_.escape之前,它会用转义像\ n这样的空白字符。我不知道为什么这很重要,它在代码中,但它与插入_.escape一起工作得很好——它也不会转义空白字符。

默认情况下,数据参数是由(数据){…}语句传递的,但这种计算比用命名变量计算要慢得多。所以用变量参数命名数据是件好事……

例如:

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 < / p >

通过模板加载,你有很多选择,但最后你总是要把模板转换成字符串。你可以像上面的例子一样给它一个普通的字符串,或者你可以从一个脚本标签加载它,并使用jquery的. html ()函数,或者你可以用require.jstpl插件从一个单独的文件加载它。

另一个选择是用简洁的而不是模板来构建dom树。

用快递就很简单了。你所需要做的就是在节点上使用巩固模块,所以你需要安装它:

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

我希望这对你有所帮助!

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

使用<%= variable =>会导致跨站脚本漏洞。所以使用<%- variable ->更安全。

我们必须将<%=替换为<%-以防止跨站点脚本攻击。不确定,这是否会对性能有影响

我举了一个非常简单的例子

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>

这是javascript代码,其中包含json对象和把模板到html

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

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