亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

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

2019-11-20 09:46:50
字體:
來源:轉載
供稿:網友

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 的作用?!皃”是調用下面 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 %>

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性高潮在线| 精品福利在线视频| 91精品国产乱码久久久久久蜜臀| 欧美在线观看一区二区三区| 日本欧美在线视频| 成人中文字幕在线观看| 亚洲福利视频免费观看| 久久久人成影片一区二区三区观看| 国产精品成av人在线视午夜片| 日韩精品极品视频免费观看| 亚洲国产中文字幕在线观看| 国内免费久久久久久久久久久| 久久久久久999| 欧美午夜精品久久久久久浪潮| 国外成人在线直播| 久久久精品久久久久| 国产小视频国产精品| 中文字幕欧美日韩在线| 国产精品十八以下禁看| 国产99久久精品一区二区永久免费| 国产成人精品a视频一区www| 亚洲bt欧美bt日本bt| 国产精品久久久久久久久久ktv| 欧美中文字幕第一页| 国产乱肥老妇国产一区二| 97视频在线观看免费高清完整版在线观看| 欧美成人免费一级人片100| 欧美成年人视频网站| 亚洲午夜久久久影院| 91av中文字幕| 高清在线视频日韩欧美| 一区二区三区四区视频| 538国产精品一区二区免费视频| 亚洲精品国产精品国产自| 欧美性受xxxx白人性爽| 91精品国产乱码久久久久久久久| 欧美做受高潮1| 北条麻妃一区二区在线观看| 91久久久久久久久久久| 成人免费在线网址| 久久国产色av| 国产亚洲免费的视频看| 国产精品久久久久久久久久东京| 国产精品免费小视频| 久久久欧美精品| 日韩精品高清在线| 91在线视频九色| 精品久久在线播放| 欧美日韩精品国产| 亚洲激情视频在线观看| 日韩av在线免费| 亚洲电影在线观看| 欧美性猛交xxxx久久久| 中文欧美在线视频| 亚洲2020天天堂在线观看| 欧美xxxx做受欧美| 午夜精品理论片| 国产精品爽爽ⅴa在线观看| 亚洲精品永久免费| 亚洲已满18点击进入在线看片| 97国产suv精品一区二区62| 国产精品视频精品| 精品久久久久久中文字幕一区奶水| 久久男人av资源网站| 亚洲欧美日韩国产成人| 日韩欧美一区二区三区久久| 日韩精品视频免费专区在线播放| 一本一本久久a久久精品综合小说| 91干在线观看| 日韩成人激情视频| 色婷婷成人综合| 成人乱色短篇合集| 精品女同一区二区三区在线播放| 欧美国产欧美亚洲国产日韩mv天天看完整| 久久久久亚洲精品国产| 国产欧美日韩精品专区| 国产精品福利无圣光在线一区| 青青久久aⅴ北条麻妃| 91国产美女视频| 久久久999精品视频| 亚洲美女av在线| 国产69久久精品成人| 国产一区视频在线播放| 日本在线观看天堂男亚洲| 欧美日韩一二三四五区| 亚洲一区二区三区视频播放| 欧美香蕉大胸在线视频观看| 国产精品久久久久久av福利| 亚洲最大福利视频网| 视频在线观看一区二区| 国产精品www色诱视频| 久久久久中文字幕2018| 国产成人在线精品| 色综合久久久久久中文网| 国产精品入口免费视| 精品一区二区三区电影| 777国产偷窥盗摄精品视频| 国产精品久久久久久久久免费看| 午夜精品一区二区三区在线视频| 国产精品影院在线观看| 欧美在线激情视频| 亚洲国产精品女人久久久| 91在线观看免费网站| 这里只有精品视频| 亚洲欧洲国产伦综合| 日本久久91av| 亚洲色图35p| 性欧美视频videos6一9| 国产激情久久久久| 国产精品美女久久久久av超清| 久久亚洲电影天堂| 欧美性极品少妇精品网站| 欧美裸身视频免费观看| 91国产精品91| 国产精品久久一区| 国产成人欧美在线观看| 欧美亚洲一区在线| 成人春色激情网| 日本欧美国产在线| 国产精品久久久久久久久久久新郎| 中文字幕精品国产| 91网站在线免费观看| 国产美女精品视频| 欧美小视频在线| 久久成人这里只有精品| 中文字幕日本精品| 91精品国产亚洲| 国产亚洲视频在线| 国产精品久久久久久久久久| 久久精品青青大伊人av| 亚洲成人精品在线| 性欧美在线看片a免费观看| 国产精品h在线观看| 日韩第一页在线| 91久久国产精品91久久性色| 亚洲精品小视频| 久久久久久久一区二区三区| 91精品美女在线| 亚洲综合日韩在线| 久久人人97超碰精品888| 成人深夜直播免费观看| 国产在线日韩在线| 久久亚洲私人国产精品va| 欧美日韩国产综合新一区| 成人欧美一区二区三区在线| 欧美激情亚洲一区| 欧美极度另类性三渗透| 91国产在线精品| 国产一区二区在线播放| 亚洲国产精品久久久久| 日韩av大片免费看| 国产手机视频精品| 亚洲精品91美女久久久久久久| 日韩在线视频国产| 国产在线精品成人一区二区三区| 亚洲国语精品自产拍在线观看| 91精品啪在线观看麻豆免费| 91午夜在线播放| 亚洲黄色av网站| 国产日韩一区在线| 91视频88av| 久久琪琪电影院| 欧美日韩在线观看视频| 91福利视频在线观看|