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 相似但短小精悍!

这里顺便贴一个高手写的(http://www.jiangkunlun.com/2012/05/js_%E6%A8%A1%E6%9D%BF/):

简单实用的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() 的形式。

网友作品:cocoTemplate

附: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');
		});
	}
}
时间: 2024-10-09 06:06:06

EJS 模板快速入门的相关文章

Smarty模板快速入门

快速入门|模板 在PHP的世界里已经出现了各式各样的模板类,但就功能和速度来说Smarty还是一直处于领先地位,因为Smarty的功能相对强大,所以使用起来比其他一些模板类稍显复杂了一点.现在就用30分钟让您快速入门. 一. 安装     首先打开网页http://smarty.php.net/download.php,下载最新版本的Smarty.解压下载的文件(目录结构还蛮复杂的).接下来我演示给大家一个安装实例,看过应该会举一反三的.     (1) 我在根目录下建立了新的目录learn/,

Smarty模板快速入门_php模板

在PHP的世界里已经出现了各式各样的模板类,但就功能和速度来说Smarty还是一直处于领先地位,因为Smarty的功能相对强大,所以使用起来比其他一些模板类稍显复杂了一点.现在就用30分钟让您快速入门. 一. 安装     首先打开网页http://smarty.php.net/download.php,下载最新版本的Smarty.解压下载的文件(目录结构还蛮复杂的).接下来我演示给大家一个安装实例,看过应该会举一反三的.     (1) 我在根目录下建立了新的目录learn/,再在learn/

Expression Blend实例中文教程(12)-样式和模板快速入门Style,Template

在上一篇,介绍了Visual State Manager视觉状态管理器,其中涉及到控件的样式(Style)和模板( Template),本篇将详细介绍样式(Style)和模板(Template)在Silverlight项目中的应用,并介绍如 何使用Blend设计样式(Style)和模板(Template). 在LOB(Line-of-Business)企业级应用项目开发中,为了使项目的视觉效果多样化,不仅仅使用动画 效果,而且经常还需要修改部分控件的样式(Style)和模板(Template).

Finecms模板标签调用小结 方便快速入门

最近接了一个单子客户要求用finecms进行建站,由于也是php代码,也可以直接调用相关函数,所以上手相对比较快,ytkah总结了一些常用的函数方便您快速入门Finecms.一个网站一般由主页.栏目页.文章页组成,常用的函数为首页调用文章.列表页调用文章.站内搜索代码.缩略图调用等,下面就随着ytkah来一起看看如何操作吧 首页调用指定栏目的文章:{list action=module catid=22 num=10},catid=22表示指定栏目为22,num表示调用的条数 {list act

Spring MVC 开发快速入门

快速入门 这篇文章将教你快速地上手使用 Spring 框架,如果你手上有一本<Spring in Action>, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦! 首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 应用程序接收到 http://localhost:8080/hello.do(事实上请求路径是 /hello.do) 的请求后, Spring 将这个请求

Toad 使用快速入门(转载)

快速入门 Toad 使用快速入门                                      目录 一.Toad功能综述二.系统需求三.安装指南四.快速入门1. Schema browser的用法简介2. SQL Editor的使用介绍3. Procedure Editor的用法介绍4. 如何进行PLSQL的debug5. 如何使用SQLab Xpert优化SQL6. 如何使用SQL Modeler来编写查询7. 如何使用Toad的DBA方面的功能 一. Toad功能综述 在Ora

toad快速入门(zz)

快速入门 一. Toad功能综述 在Oracle 应用程序的开发过程中,访问数据库对象和编写SQL程序是一件乏味且耗费时间的工作,对数据库进行日常管理也是需要很多SQL脚本才能完成的.Quest Software为此提供了高效的Oracle应用开发工具-Toad(Tools of Oracle Application Developers).在Toad的新版本中,还加入了DBA模块,可以帮助DBA完成许多日常管理工作.它最大的特点就是简单易用,访问速度快.使用 Toad,我们可以通过一个图形化的

正则表达式快速入门教程

教程|快速入门|入门教程|正则 首先,让我们来了解一下究竟什么是VBScript的"正则表达式"对象,我们先来看一段程序: Function CheckExp(patrn, strng) Dim regEx, Match ' 建立变量. Set regEx = New RegExp ' 建立正则表达式. regEx.Pattern = patrn ' 设置模式. regEx.IgnoreCase = true ' 设置是否区分字符大小写. regEx.Global = True ' 设

Docker快速入门以及环境配置详解_docker

前言 数据科学开发环境配置起来让人头疼,会碰到包版本不一致.错误信息不熟悉和编译时间漫长等问题.这很容易让人垂头丧气,也使得迈入数据科学的这第一步十分艰难.而且这也是一个完全不常见的准入门槛. 还好,过去几年中出现了能够通过搭建孤立的环境来解决这个问题的技术.本文中我们就要介绍的这种技术名叫Docker.Docker能让开发者简单.快速地搭建数据科学开发环境,并支持使用例如Jupyter notebooks等工具进行数据探索. 简介 Docker 最初 dotCloud 公司内部的一个业余项目