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);
相关选项如下:
- cache compiled functions are cached, requires filename
- filename 缓存的键名称
- scope 函数执行的作用域
- debug output generated function body
- compiledebug when false no debug instrumentation is compiled
- 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'); }); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Android中的常用尺寸单位(dp、sp)快速入门教程
-
node.js中EJS 模板快速入门教程
-
cad中怎么建立模板? cad快速画图的技巧
-
Android中的常用尺寸单位(dp、sp)快速入门教程
-
详解Django项目中模板标签及模板的继承与引用(网站中快速布置广告)
-
Word中如何快速传递文档和模板的样式以及设置主题
-
Node.JS中快速扫描端口并发现局域网内的Web服务器地址(80)
-
vs code工具中设置html5 快速生成vue模板
-
Node.js学习笔记(七) --- Node.js的静态文件托管、路 由、EJS 模板引擎、GET 、POST...
-
art-template模板引擎在node.js中的使用