Node.js的Web模板引擎ejs的入门使用教程

Node 开源模板的选择很多,但推荐像我这样的老人去用 EJS,有 Classic ASP/PHP/JSP 的经验用起 EJS 来的确可以很自然,也就是说,你能够在 <%...%> 块中安排 JavaScript 代码,利用最传统的方式 <%=输出变量%>(另外 <%-输出变量是不会对 & 等符号进行转义的)。安装 EJS 命令如下:

npm install ejs

JS 调用
JS 调用的方法主要有两个:

ejs.compile(str, options);
// => Function 

ejs.render(str, options);
// => str

实际上 EJS 可以游离于 Express 独立使用的,例如:

var ejs = require(''), str = require('fs').readFileSync(__dirname + '/list.ejs', 'utf8'); 

var ret = ejs.render(str, {
 names: ['foo', 'bar', 'baz']
}); 

console.log(ret);
见 ejs.render(),第一个参数是 模板 的字符串,模板如下。
<% if (names.length) { %>
 <ul>
 <% names.forEach(function(name){ %>
  <li foo='<%= name + "'" %>'><%= name %></li>
 <% }) %>
 </ul>
<% } %>

names 成了本地变量。

选项参数
第二个参数是数据,一般是一个对象。而这个对象又可以视作为选项,也就是说数据和选择都在同一个对象身上。
如果不想每次都都磁盘,可需要缓存模板,设定 options.filename  即可。例如:

var ejs = require('../')
 , fs = require('fs')
 , path = __dirname + '/functions.ejs'
 , str = fs.readFileSync(path, 'utf8'); 

var users = []; 

users.push({ name: 'Tobi', age: 2, species: 'ferret' })
users.push({ name: 'Loki', age: 2, species: 'ferret' })
users.push({ name: 'Jane', age: 6, species: 'ferret' }) 

var ret = ejs.render(str, {
 users: users,
 filename: path
}); 

console.log(ret);

inculde 指令
而且,如果要如

<ul>
 <% users.forEach(function(user){ %>
 <% include user/show %>
 <% }) %>
</ul>

般插入公共模板,也就是引入文件,必须要设置 filename 选项才能启动 include 特性,不然 include 无从知晓所在目录。
模板:

<h1>Users</h1> 

<% function user(user) { %>
 <li><strong><%= user.name %></strong> is a <%= user.age %> year old <%= user.species %>.</li>
<% } %> 

<ul>
 <% users.map(user) %>
</ul>

EJS 支持编译模板。经过模板编译后就没有 IO 操作,会非常快,而且可以公用本地变量。下面例子 user/show 忽略 ejs 扩展名:

<ul>
 <% users.forEach(function(user){ %>
 <% include user/show %>
 <% }) %>
</ul>

自定义 CLOSE TOKEN
如果打算使用 <h1>{{= title }}</h1> 般非 <%%>标识,也可以自定义的。

var ejs = require('ejs');
ejs.open = '{{';
ejs.close = '}}';

格式化输出也可以哦。

ejs.filters.last = function(obj) {
 return obj[obj.length - 1];
};

调用:

<p><%=: users | last %></p>

EJS 也支持浏览器环境。

<html>
 <head>
 <script src="../ejs.js"></script>
 <script id="users" type="text/template">
  <% if (names.length) { %>
  <ul>
   <% names.forEach(function(name){ %>
   <li><%= name %></li>
   <% }) %>
  </ul>
  <% } %>
 </script>
 <script>
  onload = function(){
  var users = document.getElementById('users').innerHTML;
  var names = ['loki', 'tobi', 'jane'];
  var html = ejs.render(users, { names: names });
  document.body.innerHTML = html;
  }
 </script>
 </head>
 <body>
 </body>
</html>

不知道 EJS 能否输出多层 JSON 对象呢?

对了,有网友爆料说,jQ 大神 John 若干年前写过 20 行的模板,汗颜,与 EJS 相似但短小精悍!

简单实用的js模板引擎
不足 50 行的 js 模板引擎,支持各种 js 语法:

<script id="test_list" type="text/html">
<%=
 for(var i = 0, l = p.list.length; i < l; i++){
  var stu = p.list[i];
=%>
 <tr>
  <td<%=if(i==0){=%> class="first"<%=}=%>><%==stu.name=%></td>
  <td><%==stu.age=%></td>
  <td><%==(stu.address || '')=%></td>
 <tr> 

<%=
 }
=%>
</script> 

“<%= xxx =%>”内是 js 逻辑代码,“<%== xxx =%>”内是直接输出的变量,类似 php 的 echo 的作用。“p”是调用下面 build 方法时的 k-v 对象参数,也可以在调用 “new JTemp” 时设置成别的参数名

调用:

$(function(){
 var temp = new JTemp('test_list'),
  html = temp.build(
   {list:[
     {name:'张三', age:13, address:'北京'},
    {name:'李四', age:17, address:'天津'},
    {name:'王五', age:13}
   ]});
 $('table').html(html);
});

上面的 temp 生成以后,可以多次调用 build 方法,生成 html。以下是模板引擎的代码:

var JTemp = function(){
 function Temp(htmlId, p){
  p = p || {};//配置信息,大部分情况可以缺省
  this.htmlId = htmlId;
  this.fun;
  this.oName = p.oName || 'p';
  this.TEMP_S = p.tempS || '<%=';
  this.TEMP_E = p.tempE || '=%>';
  this.getFun();
 }
 Temp.prototype = {
  getFun : function(){
   var _ = this,
    str = $('#' + _.htmlId).html();
   if(!str) _.err('error: no temp!!');
   var str_ = 'var ' + _.oName + '=this,f=\'\';',
    s = str.indexOf(_.TEMP_S),
    e = -1,
    p,
    sl = _.TEMP_S.length,
    el = _.TEMP_E.length;
   for(;s >= 0;){
    e = str.indexOf(_.TEMP_E);
    if(e < s) alert(':( ERROR!!');
    str_ += 'f+=\'' + str.substring(0, s) + '\';';
    p = _.trim(str.substring(s+sl, e));
    if(p.indexOf('=') !== 0){//js语句
     str_ += p;
    }else{//普通语句
     str_ += 'f+=' + p.substring(1) + ';';
    }
    str = str.substring(e + el);
    s = str.indexOf(_.TEMP_S);
   }
   str_ += 'f+=\'' + str + '\';';
   str_ = str_.replace(/\n/g, '');//处理换行
   var fs = str_ + 'return f;';
   this.fun = Function(fs);
  },
  build : function(p){
   return this.fun.call(p);
  },
  err : function(s){
   alert(s);
  },
  trim : function(s){
   return s.trim?s.trim():s.replace(/(^\s*)|(\s*$)/g,"");
  }
 };
 return Temp;
}();

核心是将模板代码转变成了一个拼接字符串的 function,每次拿数据 call 这个 function。

因为主要是给手机(webkit)用的,所以没有考虑字符串拼接的效率问题,如果需要给 IE 使用,最好将字符串拼接方法改为 Array.push() 的形式。

ejs模板布局 layout
1. 如果不愿意使用默认的layout.ejs,可自行指定。例如:

res.render("index",{"title":"test","layout":"main"});
// 或
res.render("index",{"title":"test","layout":"main.ejs"});

2. 如果不愿意使用layout,则可以设置layout为false,例如:

res.render("index",{"layout":false});

3. 如果不想每个请求都单独设置一次。可以使用全局设置:

app.set("view options",{
 "layout":false
});

4. ejs 里,默认的闭合标记是 <%  .. %>,我们也可以定义自己的标签。例如:

app.set("view options",{
 "open":"{{",
 "close":"}}"
});

5. 局部布局
在web应用中,经常会需要重复显示某个内容,例如:用户评论功能,需要重复显示出每一条用户的评论,这个时候,我们可以通过循环来实现。但是也可以使用【局部模版】( partial)来实现。例如:

首先我们建一个局部的模版 ./views/comment.ejs:

<div class="comment_item">
 <div class="comment_user"><%=comment.user%></div>
 <div class="comment_content"><%=comment.content%></div>
</div>

注意:这里是 comment.xxxx

然后在./views/index.ejs中,通过partial调用comment

this is <%=title%>!
<br/>
<%- partial("comment", comments)%>

注意:这里是 partial("comment.ejs", comments); <-- 单词要用复数。

最后是在router中,调用index.ejs。

 app.get("/",function(req,res){
 res.render("index",{"title":"test","layout":false,"comments":[
  {"user":"gainover","content":"test1"},
  {"user":"zongzi","content":"test2"},
  {"user":"maomao","content":"test3"}
 ]});
});

注意:代码里的 comments 和 index.ejs的 comments变量名称一致,而partial所调用的comment.ejs中,则采用 comment 的单数形式。

在列表显示时,我们通常会遇到的场景是,对第一个元素或者最后一个元素加以特殊显示。在partial中,我们可以通过express内置的变量来判断当前对象是否是第一个元素或者最后一个元素,例如:

 <div class="comment_item<%if(firstInCollection){%> firtitem <%}%>">
 <div class="comment_user"><%=comment.user%></div> :
 <div class="comment_content"><%=comment.content%></div>
</div>

这样第一条评论的 class 里就会多一个firstitem。

类似的内置变量还有:
(1)firstInCollection 如果是数组的第一个元素,则为true
(2)indexInCollection 当前元素在数组里的索引
(3)lastInCollection 如果是数组的最后一个元素,则为true
(4)collectionLength 数组的长度

最后是partial调用模版时的路径查找问题:

(1)partial("edit") 会查找同目录下的edit.ejs文件。
(2)partial("../message") 会查找上一级目录的message.ejs文件。
(3)partial("users") 会查找 users.ejs文件,如果不存在users.ejs, 则会查找 /users/index.ejs文件。

(4)<%= users %> 会对内容进行转义,想不转义,可以用 <%- users %>

(0)

相关推荐

  • 详解nodejs模板引擎制作

    关于模板,我倒是用过了不少.最开始要数Java的JSP了,然后接触了PHP的smarty,再就是Python的jinja2, Django内置模板,现在刚开始看Nodejs,也发现了不少类似的模板引擎,ejs, jade等等吧. 模板带来的最直接的好处就是加速开发,前后端分离.除此之外,对于字符串的格式化同样是个比较好的应用.习惯了python中 string = "hello {}".format("郭璞") # hello 郭璞 string = "h

  • 基于Node.js模板引擎教程-jade速学与实战1

    环境准备: 全局安装jade: npm install jade -g 初始化项目package.json: npm init --yes 安装完成之后,可以使用 jade --help 查看jade的命令行用法 一.在项目目录下新建index.jade文件 inde.jade代码: doctype html html head meta(charset='utf-8') title body h3 欢迎学习jade 1,标签按照html的缩进格式写 2,标签的属性可以采用圆括号 3,如果标签有

  • Node.js的Web模板引擎ejs的入门使用教程

    Node 开源模板的选择很多,但推荐像我这样的老人去用 EJS,有 Classic ASP/PHP/JSP 的经验用起 EJS 来的确可以很自然,也就是说,你能够在 <%...%> 块中安排 JavaScript 代码,利用最传统的方式 <%=输出变量%>(另外 <%-输出变量是不会对 & 等符号进行转义的).安装 EJS 命令如下: npm install ejs JS 调用 JS 调用的方法主要有两个: ejs.compile(str, options); //

  • Node.js 使用jade模板引擎的示例

    在"Node.js开发入门--Express安装与使用"里,我们曾经使用express generator创建了一个HelloExpress网站,express工具为我们生成了基本的目录结构.模板.stylesheet.routers等.虽然那只是一个简单的HelloWorld类的小东西,可里面包含的内容还是有些多了,为了更好的理解Express所支持的jade模板引擎的用法,我们这次提供一个手动创建的小网站,可以显示来访者的IP,并对访问进行计数. 安装jade npm instal

  • node前端开发模板引擎Jade的入门

    随着 web 发展,前端应用变得越来越复杂,基于后端的 javascript(Node.js) 也开始崭露头角,此时  javascript 被寄予了更大的期望,与此同时 javascript MVC 思想也开始流行起来.为了使用户界面与业务数据(内容)分离,就产生了『模板引擎』这个概念. 说的简单点,模板引擎就是一个字符串中有几个变量待定,通过模板引擎函数把数据动态的塞进去. 今天我们就来聊一聊 Jade 的使用方法和语法说明.Jade官网:jade-lang.com/ Jade 命令行工具

  • 快速使用node.js进行web开发详解

    首先关于node.js的学习,这里推荐一本比较好的教程,nodejs web开发指南,该书通俗易懂地将node.js语言特性讲解完之后,又从一个项目角度带领读者使用node.js学习web开发.相信这是一个比较好的学习模式和过程.由于这本书是2012年出的,书中的一个web教学项目是开发一个微博.从2012到现在,node.js及其生态环境发生了很大改变,所以关于该书的学习如果照着书本显然是过于陈旧的.到目前为止,node.js的web开发框架已经升级到了Express4.12.1,对于Mong

  • 浅谈Node.js轻量级Web框架Express4.x使用指南

    Express是一个轻量级的Web框架,简单.灵活 也是目前最流行的基于Nodejs的Web框架 通过它我们可以快速搭建功能完整的网站 (express 英文意思:特快列车) Express现在是4.x版本,更新很快,并且不兼容旧版本,导致现在市面上很多优秀的Node书籍过时 这篇文章是一篇入门级的Express使用,需要一定Node.js的基础 Web应用创建 首先要做的是下载express并引用 npm install express --save 全局安装就+个-g 引用express v

  • Node.js成为Web应用开发最佳选择的原因

    一项颠覆性的技术进入技术市场总会带来一阵震惊,但随之而来往往是被放弃.然而,Node.js 当然不是这样的情况,它是一个开源的.跨平台的基于 Chrome 的 JavaScript 运行时.Node.js 由 Ryan Dahl 于 2009 年开发,该平台现在已成为实时 Web 应用开发的独特选择,通过提供高度交互的用户体验来提高 ROI. 使用 Node.js 的最大优点是开发人员可以在客户端和服务器端编写 JavaScript.值得一提的是,像 PayPal, Yahoo, eBay, N

  • 十大 Node.js 的 Web 框架(快速提升工作效率)

    Node.js 系统含有多种不同的结构,如 MVC.全栈.REST API 和生成器等.这些结构不仅提升了 Web 应用的开发效率,也优化了开发过程.在这里,我们收集整理了十个高效的 Node.js 框架,希望对你有帮助. 1.Node.js 开发框架 Sail.js Sails.js 就像是 Node.js 平台上的 Rails 框架.这是一个可靠可伸缩的开发框架,面向服务的架构,提供数据驱动的 API 集合.用来开发多玩家游戏.聊天应用和实时面板引用非常方便,也可用于开发企业级 Node.j

  • Node.js创建Web、TCP服务器

    使用http模块创建Web服务器 Web服务器的功能: 接受HTTP请求(GET.POST.DELETE.PUT.PATCH) 处理HTTP请求(自己处理,或请求别的程序处理) 做出响应(返回页面.文件.各类数据等) 常见的Web服务器架构: Nginx.Apache:负责接受HTTP请求,确定谁来处理请求,并返回请求的结果 php-fpm / php模块:处理分配给自己的请求,并将处理结果返回给分配者 常见请求种类: 请求文件:包括静态文件(网页.图片.前端JavaScript文件.css文件

  • 使用Node.js搭建Web服务器

    1. Node.js 创建的第一个应用 1.引入http模块 var http = require("http"); 2. 创建服务器 接下来我们使用 http.createServer() 方法创建服务器,并使用 listen 方法绑定 8888 端口.函数通过 request, response 参数来接收和响应数据. //1.引入 http 模块 var http=require('http'); //2.用 http 模块创建服务 http.createServer(funct

  • Java SpringBoot模板引擎之 Thymeleaf入门详解

    目录 模板引擎简介 引入Thymeleaf模板引擎 分析Thymeleaf模板引擎 测试Thymeleaf模板引擎 1.编写一个TestController 2.编写一个测试页面 test.html 放在 templates 目录下 3.启动项目请求测试 4.结论 Thymeleaf入门: 1.修改测试请求,增加数据传输 2.使用thymeleaf 3.我们去编写下前端页面 4.启动测试! thymeleaf语法学习 1.使用任意的 th:attr 来替换Html中原生属性的值! 2.表达式语法

随机推荐