腳本模板引擎
『壹』 模板引擎的相關推薦
Smarty的特點是將模板編譯成php腳本,然後執行這些腳本。很快,非常靈活。
是一個模板類,一般也簡稱為模板。Smarty裡面有專門的模板引擎。模板的主要功能就是邏輯與顯示的分離,也就是PHP和HTML的分離。 一個簡單易用的類,可以讓你的整個網站布局基於模板文件,修改模板就能改變整個站點。
STP Simple Template Parser
一個簡單、輕量級並且易於使用的模板分析類。它可以從多個模板中組裝一個頁面,把結果頁面輸出到瀏覽器或者文件系統。 一個強大且輕量級的PEAR兼容模板系統。它是非編譯型的,使用PHP語言本身做為它的模板語言。
ETS - easy template system
可以使用完全相同數據重組模板的模板系統。 多位元組安全的模板引擎,佔用很少系統資源。它支持變數替換,內容塊可以設置顯示或隱藏。
Grafx Software』s Fast Template
一個修改版本的Fast Template系統,它包括緩存功能,調試控制台以及沉默去除為賦值塊。 這個庫的功能被設計來使用模板文件,同時允許你從HTML文件檢索信息。
htmltmpl: templating engine
一個適用於Python和PHP的模板引擎。它面向希望在項目中分離代碼和設計的web應用開發人員。
PHP Parsing Dreamweaver templates
一個分析Dreamweaver模板的簡單類,被用於Gallery 2 和WordPress的自定義模塊中。
MiniTemplator (Template Engine)
針對HTML文件的一個緊湊型模板引擎。對於模板變數和塊定義它具有簡單的語法。其中塊可以嵌套。 一個PHP下面的XML/XHTML模板庫。
『貳』 freemarker thymeleaf哪個好
我也是來問這個問題的。。。目前了解,性能方面thymeleaf更差。但是thymeleaf由於使用了標簽屬性做為語法,模版頁面直接用瀏覽器渲染,使得前端和後端可以並行開發。freemarket使用</>這樣的語法,就無法直接使瀏覽器渲染出原本頁面的樣子。
thymeleaf的性能一直是大家痛擊之處。有人說thymeleaf開啟緩存後,性能會比freemarker更好,但是開啟緩存有什麼弊端我就不知道了。(會不會更新了模版後,頁面沒變化?)
很難說兩個誰好誰壞,都有不足都有優點。目前兩者都還有更新,有團隊支持。不像velocity已經6年沒更新了。但是我看的sprint 實戰 第4版中,有一小節專門講了thymeleaf,為什麼不講freemarker,我也不懂,要問作者。為什麼IDEA中直接提供了thymeleaf的framework支持??綜上,但是為什麼網友詬病thymeleaf性能問題的更多,而誇獎的人沒有幾個??我也是迷糊了。
我是因為我的項目需要用到這些所以今天花了一天的時間,找這些資料,目前,我個人比較傾向thymeleaf。
『叄』 項目復盤:通過動態腳本,實現按需載入語言包
大家好,我是前端西瓜哥,是一名前端開發。
最近做了一個將按需載入語言包的需求,有不少收獲,這里記錄一下。
原來項目是將所有的語言包合並在一起,放到一個 JSON 文件里然後被引入。
打包後的腳本里,有完整的語言包的代碼,導致打包文件非常大。理論上用戶只會使用一種語言,其他的語言沒有載入的必要。
目前來說項目只支持兩種語言,每個語言有文案 4000 多條。如果還是使用全量載入的話,以後支持的語言每多一個,打包後的文件就要膨脹一圈。
做語言包的拆分還是很有必要的。它可以減少載入資源的大小,減少首次頁面載入時間,提高用戶體驗。
實現按需載入語言包的方式很多,我了解到的有三種:
請求 HTML 時,後端做渲染工作,給 HTML 加上語言包的內容。
前端沒有什麼改造的工作量,但問題是不能利用緩存。但這個問題其實也可以解決,就是後端生成好語言包 js 文件,將嵌入語言包內容的方式改為 cdn 引入的方式,可以利用好緩存。
但這讓模板引擎的邏輯變得很重,cdn 上傳到哪裡,如何維護也是個問題。
使用 React 等框架打包出來單頁面應用的文件通常很大,下載需要不少時間。
動態 import 必須在腳本整個下載完後,再執行,所以這是一個串列下載的邏輯。
如果可以的話,我們希望語言包可以和業務代碼同時下載。此外,更重要的一點是,在 動態 import 前,我們不能調用獲取文案的方法 getText 。
我在改造項目代碼時,發現在我動態 import 語言包並 ReactDOM.render() 之前,有些模塊文件調用了getText 方法,因為它們作為枚舉指直接暴露出來,沒有用函數封裝,被 import 時就直接執行了。
語言包都沒載入,你執行 getText 是拿不到文案的,這個方案我果斷放棄。
這種方案利用了腳本里創建腳本的方式。能在更前面的位置載入語言包腳本。
優點是我們可以不需要做後端渲染的工作,讓選擇語言包的邏輯交給前端。但涉及到前端工程化,需要寫插件改變原來的載入腳本形式。
我們的項目使用了 webpack,如果用這個方案,就需要寫一個 webpack 插件去改造 HtmlWebpackPlugin 的構建流程。
目前來說,方案 1 和 方案 3 都是不錯的。
但考慮到我們公司的前後端是分離的,後端的代碼實現對我來說其實是黑盒,我沒有許可權也沒有能力去寫後端代碼。而項目是前端項目,最好還是讓前端來掌控維護。所以我最終選擇了方案 3。
方案1 和方案 2 的更具體介紹,可以看我的這篇文章:前端國際化,該如何實現按需載入語言包?
原來項目打包後的 html 文件大致如下。
app.js 里有全量語言包的內容。
改造後的 html 文件如下:
我們語言包將 app.js 從中提取出來,並且分為多個語言包放到 js 文件,如 zh-CN.js、en-US.js,在 app.js 之前執行。
我們先確認用戶使用的語言是什麼。
如果我們不支持持久化設置,可以通過 navigator.language 或前端的其他地方獲取。
但通常用戶可以設置語言,這個語言標識就要後端給,再請求一次用戶信息可太離譜了,所以這里還是需要後端給我們往 html 里嵌入用戶選擇的語言。然後我們從語言 cdn 列表裡選我們需要的語言。
script 元素默認會將 async 設置為 true,效果是腳本下載完立即執行。需要將其改為 false,保證多個動態腳本順序執行。
文件名使用了哈希,是為了解決瀏覽器緩存問題。
執行後,就會將語言包文案暴露在全局變數中。
業務代碼 app.js 也得改成動態載入形式,如果原來的非動態寫法,執行時機就會早於語言包腳本 。
這里涉及到了 script 的執行時機,具體規則可以看我的這篇文章:script 的三種載入模式:默認載入、defer、async
這樣我們就能保證先執行語言包腳本,再執行 app.js。
app.js 中的業務代碼執行時,使用 getText 方法就能正常通過 key 獲取到對應的文案。
這里 app.js 改為動態的寫法後,需要腳本解析執行後才下載腳本,可以考慮加個 link preload 提前下載腳本。
link 的 preload 作用可以看我的這篇文章。
思路並不復雜,但改造過程中做了很多工作,遇到了不少問題。這里簡單列舉一下,不展開講了,到時候會考慮另寫文章討論。
行文有點倉促,想到什麼寫什麼,希望對你做按需載入語言方案有一定的幫助。
我是啥都寫寫的前端西瓜哥,歡迎關注我。
『肆』 nodejs鍐呯疆妯″潡鏈夊摢浜
涓銆丒xpress妗嗘灦
鍓嶉潰鐨勭珷鑺傚凡緇忎粙緇嶈繃浜嗭紝鍙浠ヤ嬌鐢╪pm鏉ュ畨瑁卬ode.js妯″潡銆傚叿浣撴搷浣滆峰弬鐓т互鍓嶅啓鐨刵odejs姒傝恆
Express鏄涓涓猲odejs鐨剋eb寮婧愭嗘灦錛岀敤浜庡揩閫熺殑鎼寤簑eb欏圭洰銆傚叾涓昏侀泦鎴愪簡web鐨刪ttp鏈嶅姟鍣ㄧ殑鍒涘緩銆侀潤鎬佹枃鏈綆$悊銆佹湇鍔″櫒URL鍦板潃璇鋒眰澶勭悊銆乬et鍜宲ost璇鋒眰澶勭悊鍒嗗彂銆乻ession澶勭悊絳夊姛鑳姐
浣跨敤鏂規硶錛屽湪cmd涓鎵撳紑浣犳墍鎯沖壋寤簑eb欏圭洰鐨勮礬寰勩傜劧鍚庤緭鍏
Express appname
鍗沖彲鍒涘緩涓涓鍚嶄負appname鐨剋eb欏圭洰銆傛帶鍒跺彴鎵撳嵃緇撴灉
鍦╦ada鏂囦歡涓鏄鍙浠ヤ嬌鐢╢or寰鐜鍜宨f鍒ゆ柇璇鍙ョ殑錛屽彲浠ヨ╀綘浣撲細綾諱技JSP鐨<%%>鍜宲hp鐨<php></php>鍦ㄧ綉欏典笂杈撳嚭鏁版嵁鐨勫揩鎰熴
涓夈乫orever妯″潡
nodejs浣滀負http鏈嶅姟鍣錛岄渶瑕佺『淇濇湇鍔¢『鍒╄繘琛岋紝瑕佹敞鎰忎竴涓嬩袱鐐癸細
1.鍚庡彴鏈嶅姟榪愯岋紝鐩戞帶榪愯屾棩蹇楋紝浠ュ強http榪愯屾棩蹇楋紱
2.紜淇濋」鐩鐨勬e父瀹夊叏榪愯岋紝Node.js鐨勫惎鍔ㄥ懡浠node錛屽緢澶х▼搴︽棤娉曟弧瓚寵繍琛岄渶奼傦紱
Node.js鐨刦orever妯″潡鍦ㄧ浜岀偣灝卞彲浠ヨ搗鍒板緢澶х殑浣滅敤錛屽悓鏃跺叾鎷ユ湁鐩戞帶鏂囦歡鏇存敼銆佽嚜鍔ㄩ噸鍚絳夊姛鑳姐
forever妯″潡鐨勪嬌鐢ㄦ柟娉曟湁涓ょ嶏細1.鍦ㄥ懡浠よ屼腑浣跨敤
forever -l forever.log -o out.log -e err.log app.js
-l forever.log -o out.log -e err.log鍒嗗埆鎸囧畾浜唂orever鐨勮繍琛屾棩蹇楋紝鑴氭湰嫻佹按鏃ュ織錛岃剼鏈榪愯岄敊璇鏃ュ織錛屽惎鍔ㄥ悗灝嗗湪鏈鏂囦歡澶逛笅浜х敓out.log銆乪rr.log鏂囦歡銆
2.鍦ㄧ紪鐮佷腑require forever妯″潡浣跨敤銆
鍥涖丼ocket.IO妯″潡
Socket.IO妯″潡涓昏佸姛鑳芥槸灝哤ebSocket鍗忚搴旂敤鍒版墍鏈夋祻瑙堝櫒銆備富瑕佺敤浜庡疄鏃剁殑闀胯繛鎺ュ氭眰鎯呴」鐩涓銆
渚嬪傦細鍦ㄧ嚎鑱旂綉娓告垙錛屽疄鏃惰亰澶┿佸疄鏃惰偂紲ㄦ煡鐪嬨佷簩緇寸爜鎵鎻忕櫥褰曠瓑銆
瀹夎呮柟娉曚粛鐒舵槸鍦╟md鍦ㄤ腑杈撳叆npm install socket.io
濡備綍浣跨敤Socket.IO鏉ュ壋寤轟竴涓欏圭洰銆
闇瑕佸垎鍒瀹炵幇鏈嶅姟絝鍜屽㈡埛絝鐨勯昏緫錛
鍏堝壋寤轟竴涓鏈嶅姟絝鐨刵ode.js鑴氭湰index_server.js
var app = require('http').createServer(handler)//鍒涘緩鏈嶅姟鍣╝pp
, io = require('socket.io').listen(app)//寮曠敤socket.io妯″潡鐩戝惉app
, fs = require('fs')//寮曠敤鏂囦歡澶勭悊妯″潡
app.listen(80);//鎸囧畾app鐩戝惉鐨勭鍙o紝絎浜屼釜鍙傛暟127.0.0.1鍙鐪佺暐
function handler (req, res) {
fs.readFile(__dirname + '/index.html', function (err, data) { if (err) {
res.writeHead(500); return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
鍏朵腑錛宻ocket.emit()涓篠ocket鍙戦佹秷鎮鐨勫嚱鏁幫紝絎涓涓鍙傛暟琛ㄧず鍙戦佹秷鎮鐨刱ey鍊礆紝絎浜屼釜鍙傛暟涓哄彂閫佹秷鎮鐨勫唴瀹癸紝涔熷氨鏄鍙戦佺殑鏁版嵁銆
Socket銆俹n()涓篠ocket鎺ユ敹娑堟伅鐨勫嚱鏁幫紝絎涓涓鍙傛暟涓烘帴鏀舵秷鎮鐨勫彲浠ュ礆紝絎浜屼釜鍙傛暟涓哄洖璋冨嚱鏁幫紝鍏朵腑鍥炶皟鍑芥暟鎼哄甫鐨勫弬鏁頒負鎺ユ敹娑堟伅鎵鍙戦佺殑鏁版嵁銆
鎺ヤ笅鏉web鍓嶇濡備綍浣跨敤javaScrit 鏉ヨ繛鎺Socket鏈嶅姟鍣ㄣ
鏂板緩涓涓猧ndex_client.html
<script type="text/javascript" src="socket.js"></script>
<script type="text/javascript"> var socket = io.connect('http://localhost');//鍒涘緩鏈鍦皊ock榪炴帴
socket.on('news',function (data) {//Socket鎺ユ敹news娑堟伅鏃舵墽琛屽洖璋冨嚱鏁 console.log(data);
socket.emit('my other event',{my:'data'});
});</script>
<script type="text/javascript" src="socket.js"></script>鍔犺澆宸茬粡瀹夎呭ソ鐨凷ocket.io鐨勬湰鍦癑avaScrit鏂囦歡銆
var socket = io.connect('http://localhost');鍥犱負絝鍙d負80錛屾墍鏈夎繖閲屽彲浠ヤ笉絝鍙e彿
socket.on('news',function (data)鍀涳綕//瀹㈡埛絝鎺ユ敹news娑堟伅鎴愬姛鍚庯紝鍙戦乵y other event娑堟伅鍒版湇鍔$錛屽彂閫佺殑娑堟伅鍐呭逛負json瀵硅薄{my:'data'}
鎺ヤ笅鏉ュ彧闇瑕佽繍琛屾湇鍔$鐨剗ndex_server.js鏂囦歡鏉ュ惎鍔╯ocket鏈嶅姟
鏁堟灉錛氬湪嫻忚堝櫒杈撳叆http://127.0.0.1鎸塅12璋冨嚭嫻忚堝櫒鐨勬帶鍒跺彴console鍗沖彲鐪嬭佹墦鍗板嚭浜嗕竴涓猳bject瀵硅薄銆
鎵ц屽畬姣曞悗鍙鑳戒細鎶ラ敊錛歝atnot find mole socket.io錛岃存槑浣犵殑socket.IO娌℃湁瀹夎咃紝鎴栧凡緇忓畨瑁呭苟閰嶇疆涓哄叏灞錛屼絾浣犵殑瀹夎呰礬寰勫苟娌℃湁閰嶇疆鍒板湪path涓錛屾墍鏈夋棤娉曞紩鐢ㄣ
浣犲彲浠ラ夋嫨閰嶇疆path錛屾垨鑰呭畨瑁呭埌欏圭洰鍐呫傝繖閲屽緩璁瀹夎呭埌浣犵殑欏圭洰鐩褰曚笅錛岃屼笉鏄綆鍗曠矖鏆寸殑閰嶇疆涓哄叏灞銆傚厛鍗歌澆npm uninstall socket.io 榪涘叆鎸囧畾鐩褰曞悗瀹夎卬ode index_server.js
socket.io璇︾粏璇峰弬闃 http://cnodejs.org/topic/50a1fcc7637ffa4155b5a264
浜斻乺equest妯″潡
request妯″潡涓哄紑鍙戣呮彁渚涗簡涓縐嶇畝鍗曡塊棶HTTP璇鋒眰鐨勬柟娉曘俽equest榪樻敮鎸丠TTPS鐨勮塊棶鏂規硶銆
瀹夎咃細
npm install requset
request妯″潡鍩烘湰涓婅嗙洊浜嗘墍鏈夌殑HTTP璇鋒眰鏂瑰紡濡侴ET錛孭OST錛孒EAD錛孌EL絳夈備絾鍏舵渶鍩烘湰鐨勪袱涓鏂規硶鏄痳equest.get()鍜宺equest.post().
get鍜宲ost鐨勫尯鍒
get錛
1.浣跨敤get鍚戞湇鍔″櫒鍙戝嚭鍜屾帴鏀剁殑璇鋒眰浼氶檮鍦╱rl涔嬪悗銆傜被浼礆細http://www..com錛焛d=1221&name=5555榪欎釜url涓浼犻掍簡涓や釜鍙傛暟錛屼竴涓涓篿d錛屼竴涓涓簄ame銆
2.get璇鋒眰涓嶈兘瓚呰繃1024涓瀛楄妭銆
post娌℃湁闄愬埗錛屼篃涓嶄細闄勫湪url涓娿
鎺ヤ笅鏉ュ仛涓涓綆鍗曠殑瀹炰緥
get瀹炰緥錛
棣栧厛鏂板緩涓涓鏈嶅姟鍣╝pp_get.js
var http= require("http");
http.createServer(function(req,res){
res.writeHead(200,{'content-Type':'text/plain'});
res.end('Hello world
'+req.method);
}).listen(1337,"127.0.0.1");
鍐嶅緩涓涓鍙戦佹眰鎯呯殑request_get.js鏂囦歡
var request=require('request');
request.get("http://127.0.0.1:1337",function(error,response,result){
console.log(result);
});
鍦–MD涓榪愯宎pp_get.js錛岃繍琛屾垚鍔熷悗錛屽啀鎵撳紑涓涓猚md錛堜箣鍓嶇殑cmd涓嶈佸叧闂錛夛紝鎵ц宺equest_get.js鏂囦歡銆
鎵ц屽悗鐨勭粨鏋滃備笅
hello world
GET
鍙浠ョ湅鍑猴紝閫氳繃request.get鏂規硶璁塊棶
http://127.0.0.1:1337 榪斿洖鐨勭粨鏋滃氨鏄痳es.end錛堬級鐨勫弬鏁
post瀹炰緥錛
鍜屼笂闈涓鏍鳳紝鍏堟柊寤烘湇鍔″櫒app_post.js
var http= require("http"),
querystring=require('querystring');
http.createServer(function(req,res){ var postData=""; //寮濮嬪紓姝ユ帴鏀跺㈡埛絝痯ost鐨勬暟鎹
req.addListener("data",function (postDataChunk) {
postData += postDataChunk;
}); //寮傛post鏁版嵁鎺ユ敹瀹屾瘯鍚庢墽琛屽尶鍚嶅洖璋冨嚱鏁
req.addListener("end",function(){ var postStr=JSON.stringify(querystring.parse(postData));
res.writeHead(200,{'content-Type':'text/plain'});
res.end(postStr+'
'+req.method);
});
}).listen(1400,"127.0.0.1");
鐒跺悗鍐嶆柊寤轟竴涓猺equest_post.js
var request=require("request");
request.post('http://127.0.0.1:1400',{form:{'name':'ermu','book':'node.js'}},function (error,response,result) {
console.log(result);
})
鍍忎笂闈涓鏍峰湪cmd涓鎵ц屽悗鏄劇ず鐨勭粨鏋滃備笅錛
D:
odejssrc
equest>node request_post.js
{"name":"ermu","book":"node.js"}
POST
request post鎻愪氦浜嗕竴涓猨son瀵硅薄{"name":"ermu","book":"node.js"}鑰屾湇鍔″櫒鎺ラ氳繃鑾峰彇璇POST鏁版嵁錛岀劧鍚庤繑鍥炲㈡埛絝錛屽悓鏃跺皢http璇鋒眰鏂瑰紡涔熷搷搴斿埌瀹㈡埛絝銆
request post鍙傛暟鍙浠ユ湁涓ょ嶄紶閫掓柟寮忋
鍏朵腑錛岀涓縐嶆槸灝唘rl鍜宖orm琛ㄥ崟鐨勬暟鎹浣滀負json鍙傛暟鍦╮equest post浼犻掋備婦渚嬪備笅錛
request.post('url':'http://127.0.0.1:1400',form:{'name':'ermu','book':'node.js'}},function (error,response,result) {
console.log(result);
})
鍙︿竴縐嶆槸灝唘rl鍜宖orm浣滀負涓や釜鍙傛暟錛屼笂闈㈢殑瀹炰緥灝辨槸浣跨敤榪欑嶆柟娉曘
鍏銆 Formidable妯″潡
璇ユā鍧楃殑鐩鐨勬槸涓轟簡瑙e喅鏂囦歡涓婁紶銆
鍦ㄥ師鐢熺殑node.js妯″潡涓錛屾彁渚涗簡鑾峰彇post鏁版嵁鐨勬柟娉曪紝浣嗘槸騫舵病鏈夌洿鎺ヨ幏鍙栦笂浼犳枃浠躲