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() 的形式。
附: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');
});
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# ejs快速入门教程
# ejs
# 模板快速入门
# node
# ejs模板
# node.js报错:Cannot find module ''ejs''的解决办法
# Node.js的Web模板引擎ejs的入门使用教程
# Node.js项目中调用JavaScript的EJS模板库的方法
# node.js 使用ejs模板引擎时后缀换成.html
# node.js中使用ejs渲染数据的代码实现
# 成了
# 自定义
# 是一个
# 也就是说
# 加载
# 短小精悍
# 都在
# 第一个
# 则是
# 大神
# 第二个
# 扩展名
# 会对
# 天津
# 只需要
# 每次都
# 人去
# 则为
# 北京
# 文件系统
相关文章:
网站制作服务平台,有什么网站可以发布本地服务信息?
c# 服务器GC和工作站GC的区别和设置
开源网站制作软件,开源网站什么意思?
如何快速启动建站代理加盟业务?
建站主机选择指南:服务器配置与SEO优化实战技巧
如何快速搭建高效可靠的建站解决方案?
常州自助建站:操作简便模板丰富,企业个人快速搭建网站
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
北京营销型网站制作公司,可以用python做一个营销推广网站吗?
如何制作网站标识牌,动态网站如何制作(教程)?
大同网页,大同瑞慈医院官网?
如何访问已购建站主机并解决登录问题?
黑客入侵网站服务器的常见手法有哪些?
文字头像制作网站推荐软件,醒图能自动配文字吗?
郑州企业网站制作公司,郑州招聘网站有哪些?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
建站之星微信建站一键生成小程序+多端营销系统
如何快速完成中国万网建站详细流程?
如何通过服务器快速搭建网站?完整步骤解析
如何在腾讯云免费申请建站?
上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?
建站主机如何选?高性价比方案全解析
制作公司内部网站有哪些,内网如何建网站?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
制作证书网站有哪些,全国城建培训中心证书查询官网?
建站之星展会模版如何一键下载生成?
金*站制作公司有哪些,金华教育集团官网?
专业网站设计制作公司,如何制作一个企业网站,建设网站的基本步骤有哪些?
存储型VPS适合搭建中小型网站吗?
制作网站的基本流程,设计网站的软件是什么?
陕西网站制作公司有哪些,陕西凌云电器有限公司官网?
网站制作报价单模板图片,小松挖机官方网站报价?
网站代码制作软件有哪些,如何生成自己网站的代码?
教学论文网站制作软件有哪些,写论文用什么软件
?
建站ABC备案流程中有哪些关键注意事项?
建站为何优先选择香港服务器?
如何选择高效响应式自助建站源码系统?
制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?
如何快速上传建站程序避免常见错误?
广德云建站网站建设方案与建站流程优化指南
如何用美橙互联一键搭建多站合一网站?
建站主机类型有哪些?如何正确选型
内网网站制作软件,内网的网站如何发布到外网?
如何在自有机房高效搭建专业网站?
交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?
网站制作哪家好,cc、.co、.cm哪个域名更适合做网站?
如何在七牛云存储上搭建网站并设置自定义域名?
如何快速搭建响应式可视化网站?
网站制作费用多少钱,一个网站的运营,需要哪些费用?
*请认真填写需求信息,我们会在24小时内与您取得联系。