node.js中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); 

相关选项如下:

  1. cache Compiled functions are cached, requires filename
  2. filename 缓存的键名称
  3. scope 函数执行的作用域
  4. debug Output generated function body
  5. compileDebug When false no debug instrumentation is compiled
  6. client Returns standalone compiled function

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() 的形式。

附:connect + ejs 的一个例子。

var Step = require('../../libs/step'),
  _c = require('./utils/utils'),
  fs = require('fs'),
  ejs = require('ejs'),
  connect = require('connect'); 

exports.loadSite = function(request, response){
  var siteRoot = 'C:/代码存档/sites/a.com.cn';
  // _c.log(request.headers.host); 

  var url = request.url;
  // 如果有 html 的则是动态网页,否则为静态内容
  if(url == '/' || ~url.indexOf('/?') || url.indexOf('.asp') != -1 || url[url.length - 1] == '/'){
    var tplPath; 

    if(url == '/' || ~url.indexOf('/?') || url[url.length - 1] == '/'){
      // 默认 index.html
      tplPath = siteRoot + request.url + 'default.asp';
    }else{
      tplPath = siteRoot + request.url.replace(/\?.*$/i,''); // 只需要文件名
    } 

    // 从文件加载模板
    Step(function(){
      _c.log('加载模板:' + tplPath);
      fs.exists(tplPath, this);
    }, function(path_exists){
      if(path_exists === true)fs.readFile(tplPath, "utf8", this);
      else if(path_exists === false) response.end404(request.url);
      else response.end500('文件系统异常', '');
    },function(err, tpl){ 

      var bigfootUrl, cssUrl, projectState = 0; // 0 = localhot/ 1 = Test Server / 2 = Deployed
      switch(projectState){
        case 0:
           bigfootUrl = "http://127.0.0.1/bigfoot/";
           cssUrl   = "http://127.0.0.1/lessService/?isdebug=true";
        break;
        case 1:
           bigfootUrl = "http://112.124.13.85:8080/static/";
           cssUrl   = "/asset/style/";
        break;
        case 2:
           bigfootUrl = "http://localhost:8080/bigfoot/";
        break;
      } 

      var sitePath = request.getLevelByUrl(require(siteRoot + '/public/struct')),
        first = sitePath[0];
      var htmlResult = ejs.render(tpl, {
        filename : tplPath,
        bigfootUrl: bigfootUrl,
        cssUrl : cssUrl,
        projectState: projectState,
        query_request: request.toJSON(),
        request: request,
        config: require(siteRoot + '/public/config'),
        struct: require(siteRoot + '/public/struct'),
        sitePath : sitePath,
        firstLevel : first
      });
      // _c.log(first.children.length)
      response.end200(htmlResult);
    }); 

  }else{
    connect.static(siteRoot)(request, response, function(){
      // if not found...
      response.writeHead(404, {'Content-Type': 'text/html'});
      response.end('404');
    });
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

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

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

  • node.js中EJS 模板快速入门教程

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

  • Node.js中Express框架的使用教程详解

    目录 Express简介 Express生成器 1. 什么是Express生成器 2. 安装Express生成器 创建Express项目 安装项目依赖 运行Express项目 Express目录结构说明 创建一个新路由模块 1. 创建ejs模块文件 2. 创建路由文件 3. 在app.js中引入路由 4. 运行项目 经过前面几天对Node.js的学习,基本的开发知识已经逐渐掌握,所谓工欲善其事必先利其器,今天进一步学习Node.js的开发框架Express.利用Express框架可以快速的进行W

  • node.js中get和post接口教程

    目录 接口传参 express写get接口 get无传参的最简单 get有传参 post请求 post传递普通键值对 post传递JSON格式 post接口-form-data文件上传 接口传参 我们使用ajax请求向服务器接口传参,按http协议的约定,每个请求都有三个部分: 请求行: 保存了请求方式,地址,可以以查询字符串的格式附加一部分数据. 请求头:它可以附加很多信息,其中content-type用来约定请求体中保存的数据格式. content-type常见有三种取值: content-

  • node.js中的socket.io入门实例

    关于websocket等反向ajax技术介绍 在实时web应用中,常见的方法是反向Ajax.反向Ajax的定义: 反向Ajax(Reverse Ajax)本质上则是这样的一种概念:能够从服务器端向客户端发送数据.在一个标准的HTTP Ajax请求中,数据是发送给服务器端的,反向Ajax可以某些特定的方式来模拟发出一个Ajax请求,这些方式本文都会论及,这样的话,服务器就可以尽可能快地向客户端发送事件(低延迟通信). 反向Ajax技术主要有两点内容:一是服务器端保持住TCP连接直到其有数据发送给客

  • node.js 使用ejs模板引擎时后缀换成.html

    这是一个小技巧,看着.ejs的后缀总觉得不爽,使用如下方法,可以将模板文件的后缀换成我们习惯的.html. 1.在app.js的头上定义ejs: 复制代码 代码如下: var ejs = require('ejs'); 2.注册html模板引擎: 复制代码 代码如下: app.engine('html',ejs.__express); 3.将模板引擎换成html: 复制代码 代码如下: app.set('view engine', 'html'); 4.修改模板文件的后缀为.html. 好了,任

  • node.js中cluster的使用教程

    本文主要给大家介绍了关于node.js中cluster使用的相关教程,分享出来供大家参考学习,下面来看看详细的介绍: 一.使用NODE中cluster利用多核CPU var cluster = require('cluster'); var http = require('http'); var numCPUs = require('os').cpus().length; if (cluster.isMaster) { // 创建工作进程 for (var i = 0; i < numCPUs;

  • Vue.js快速入门教程

    像AngularJS这种前端框架可以让我们非常方便地开发出强大的单页应用,然而有时候Angular这种大型框架对于我们的项目来说过于庞大,很多功能不一定会用到.这时候我们就需要评估一下使用它的必要性了.如果我们仅仅需要在一个简单的网页里添加屈指可数的几个功能,那么用Angular就太麻烦了,必要的安装.配置.编写路由和设计控制器等等工作显得过于繁琐. 这时候我们需要一个更加轻量级的解决方案.Vue.js就是一个不错的选择.Vue.js是一个专注于视图模型(ViewModal)的框架.视图模型是U

  • NodeJS中的MongoDB快速入门详细教程

    MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 一.MongoDB必须理解的概念 1.数据库:每个数据库都有自己的权限和集合. 2.文档:一个键值对. 3.集合:一组文档,即一组键值对.当第一个文档插入时,集合就会被创建. 二.Mac下的MongoDB安装和启动 1.使用brew进行安装:brew ins

  • Vue.js 60分钟快速入门教程

    vuejs是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能够快速地上手并使用Vue.js. 如果你之前已经习惯了用jQuery操作DOM,学习Vue.js时请先抛开手动操作DOM的思维,因为Vue.js是数据驱动的,你无需手动操作DOM.它通过一些特殊的HTML语法,将DOM和数据绑定起来.一旦你创建了绑定,DOM将和数据保持同步,每当变更了数据,DOM也会相应地更新. 当

  • Node.JS中快速扫描端口并发现局域网内的Web服务器地址(80)

    在 Node.JS 中进行端口扫描还是比较方便的,一般会有广播和轮询两种方式.即使用广播和扫描,使用广播发出的消息有时会被路由器屏蔽,所以并不可靠. 使用node.js中的net模块,可以直接尝试向目录主机的某个端口进行连接,如果能建立连接,则说明该地址存在服务器. var socket = new Socket() socket.connect(port, host) socket.on('connect', function() { //找到port 和 host 地址 }) 所以只要进行2

随机推荐