官方網址:http://trimpath.com/project/wiki/JavaScriptTemplates
Trimpath JavaScript 是個輕量級的,基於JavaScript的,跨瀏覽器,採用APL/GPL開放原始碼協議的,可以讓你輕鬆進行基於模板編程方式的純JS引擎。
引用內容它有如下的特點:
1、採用標準的JavaScript編寫,支援跨瀏覽器
2、模板文法類似於:FreeMarker,Velocity,Smarty
3、採用簡易的語言來描述大段的字串以及Dom/DHTML操作
4、可以很方便的解析XML檔案格式的資料到指定模板。
采 用該引擎,可以讓它來完全處理View方面的事情,服務端Module直接輸出Data就可以。讓你的MVC模式連成一體,而且由於View由瀏覽器來處 理,大大減少了伺服器的負擔,用來構建Ajax技術的網路資訊系統應用是一個非常好的選擇。下面將通過翻譯該站的文章來給大家介紹這個JST引擎的使用。
網站地址:
http://trimpath.com/project/wiki/JavaScriptTemplates
如果大家等不及看我翻譯或者不滿意翻譯品質,請看上面網站的英文原文。
快速示範:
引用內容<html>
<head>
<script language="javascript" src="trimpath/template.js"></script>
</head>
<body>
<div id="outputDiv">
</div>
<script language="javascript">
var data = {
products : [ { name: "mac", desc: "computer",
price: 1000, quantity: 100, alert:null },
{ name: "ipod", desc: "music player",
price: 200, quantity: 200, alert:"on sale now!" },
{ name: "cinema display", desc: "screen",
price: 800, quantity: 300, alert:"best deal!" } ],
customer : { first: "John", last: "Public", level: "gold" }
};
</script>
<textarea id="cart_jst" style="display:none;">
Hello ${customer.first} ${customer.last}.<br/>
Your shopping cart has ${products.length} item(s):
<table>
<tr><td>Name</td><td>Description</td>
<td>Price</td><td>Quantity & Alert</td></tr>
{for p in products}
<tr><td>${p.name|capitalize}</td><td>${p.desc}</td>
<td>$${p.price}</td><td>${p.quantity} : ${p.alert|default:""|capitalize}</td>
</tr>
{forelse}
<tr><td colspan="4">No products in your cart.</tr>
{/for}
</table>
{if customer.level == "gold"}
We love you! Please check out our Gold Customer specials!
{else}
Become a Gold Customer by buying more stuff here.
{/if}
</textarea>
<script language="javascript">
// The one line processing call...
var result = TrimPath.processDOMTemplate("cart_jst", data);
// Voila! That's it -- the result variable now holds
// the output of our first rendered JST.
// Alternatively, you may also explicitly parse the template...
var myTemplateObj = TrimPath.parseDOMTemplate("cart_jst");
// Now, calls to myTemplateObj.process() won't have parsing costs...
var result = myTemplateObj.process(data);
// Setting an innerHTML with the result is a common last step...
document.getElementById("outputDiv").innerHTML = result;
// You might also do a document.write() or something similar...
</script>
</body>
</html>
實際效果:
JST十分鐘簡介
JST API
JST Markup Syntax
JST Standard Modifiers
JST Downloads
JST Community Wiki
JST Browser Compatibility
JST Online Demo
1、API
首先到下載頁面下載 template.js
然後在你的JSP/ASP/PHP等檔案中引用
引用內容<script language="javascript" src="trimpath/template.js"></script>
當你引用了template.js檔案之後,指令碼將建立一個名叫“trimpath"的物件給你使用。
TrimPath Object
這個物件是一個全域的單一變數,也是所有trimpath組件的訪問入口,除了它自身,我們嘗試建立一個清晰的命名空間給您使用。
下面是 Trimpath 定義的方法:
TrimPath.parseDOMTemplate ( elementId, optionalDocument )
得到頁面中ID為elementId的Dom組件的InnerHTML,並將其解析成一個模板,這個方法返回一個templateObject對象(下面將詳細描述),解析出錯時將拋出一個異常,下面是這個方法的參數:
elementId DOM組件,其innerhtml將用來做模板
optionalDocument 一個選擇性參數,在使用iframe,frameset或者預設多文檔時會有用
通常用來做模板的DOM元素是一個隱藏的<textarea>,如下面的例子
引用內容<textarea id="elementId" style="display:none;"> template body </textarea>
TrimPath.processDOMTemplate ( elementId, contextObject, optionalFlags, optionalDocument )
一 個輔助函數,裡面調用了TrimPath.parseDOMTemplate() 和 then the process() 方法以獲得templateObject。輸出的是templateObject.process() 中返回的對象。解析出錯時將拋出一個錯誤。
引用內容下面是這個方法的參數:
elementId 包含模板內容的DOM元素ID
contextObject 參考templateObject.process()
optionalFlags 參考templateObject.process()
optionalDocument 參考TrimPath.parseDOMTemplate
TrimPath.parseTemplate ( templateContentStr, optionalTemplateName )
解析模板方法,將一個字串做為模板解析並返回一個templateObject
參數表:
引用內容templateContentStr 符合JST文法的字串,例如: "Hello ${firstName} ${lastName}"
optionalTemplateName 一個可選的字串用來指定模板名稱,輔助查錯。
The templateObject
TrimPath.parseTemplate() 和 TrimPath.parseDOMTemplate()的成功運行將產生一個 templateObject 它只有一個主方法
templateObject.process ( contextObject, optionalFlags )
這個方法將模板和資料結合在一起,可以重複調用,如果沒有重新解析,templateObjects的緩衝和重用將獲得最好的系統效能。這個函數的傳回值是一個經過“渲染”過的模板的字串。
引用內容參數contextObject 必須是一個對象,並將成為模板的一個訪問域,比如一個模板是:${a},那麼contextObject.a必須是可以訪問到的。同樣${a.b.c}, contextObject.a.b.c也是可以訪問到的。
注 意:contextObject 可以是javascript中的任意對象,包含字串, 數字, 日期, 對象和函數。所以${groupCalender(new Date())} 可以這樣來調用contextObject.groupCalender(new Date())。當然,你必須自己編程實現groupCalender() 這個函數。
引用內容參數optionalFlags 可以是空值,也可以是一個下面列表描述的對象:
throwExceptions 預設是false,當true的時候,process() 方法將重新拋出異常,當false的時候,任何異常將停止解析模板,並在方法傳回值包含一個出錯資訊。
keepWhitespace 預設是falsel,當值為true時,模板的空白將保留。當為false時,空白(換行、空格、TAB)將被截取。
String.prototype.process() 方法
String.prototype.process ( contextObject, optionalFlags )
做為一個便捷的方式為string對象加入一個process()的方法,讓它來執行解析模板的動作。參數跟process()一樣。
引用內容 var result = "hello ${firstName}".process(data)
// ...is equivalent to...
var result = TrimPath.parseTemplate("hello ${firstName}").process(data);
添加自訂標識符
如果要採用自訂標識符,你必須把他們放在_MODIFERS 這個對象中,這些標識符集將被添加到contextObject 對象中,然後最終傳給process()解析。每一個自訂標識符必須是一個函數並且至少有一個字串參數輸入和一個字串輸出。
例子:
引用內容var myModifiers = {
hello : function(str, greeting) {
if (greeting == null)
greeting = "Hello";
return greeting + ", " + str;
},
zeroSuffix : function(str, totalLength) {
return (str + "000000000000000").substring(0, totalLength);
}
};
var myData = {
firstName : "John",
getCurrentPoints : function() { /* Do something here... */ return 12; }
}
myData._MODIFIERS = myModifiers;
"${firstName}".process(myData) == "John"
"${firstName|hello}".process(myData) == "Hello, John"
"${firstName|hello:"Buenos Dias"}".process(myData) == "Buenos Dias, John"
"${firstName|hello:"Buenos Dias"|capitalize}".process(myData) == "BUENOS DIAS, JOHN"
"${getCurrentPoints()}".process(myData) == "12"
"${getCurrentPoints()|zeroSuffix:4}".process(myData) == "1200"
JST 的文法和語句
文法
引用內容${expr}
${expr|modifier}
${expr|modifier1|modifier2|...|modifierN}
${expr|modifier1:argExpr1_1}
${expr|modifier1:argExpr1_1,argExpr1_2,...,argExpr1_N}
${expr|modifier1:argExpr1_1,argExpr1_2|...|modifierN:argExprN_1,argExprN_2,...,argExprN_M}
運算式可以是除了“}”之外的任何合法的javascript字串
標識符看起來像這種結構:modifierName[:argExpr1[,argExpr2[,argExprN]]]
一個帶參數的運算式例子
引用內容${customer.firstName}
${customer.firstName|capitalize}
${customer.firstName|default:"no name"|capitalize}
${article.getCreationDate()|default:new Date()|toCalenderControl:"YYYY.MM.DD",true,"Creation Date"}
${(lastQuarter.calcRevenue() - fixedCosts) / 1000000}
一個運算式也可以像下面一樣通過添加“%”字元來標識,這個可以避免在你的運算式中出現“}”時出錯的情況。
比如:
引用內容Visit our ${% emitLink('Solutions and Products',
{ color: 'red', blink: false }) %} page.
The extra spaces are actually not necessary, like...
${%customer.firstName%}
${%customer.firstName|capitalize%}
語句
JST語句就像是javascript語句一樣,也有if/else/for/function這些句子
分支控制語句
引用內容{if testExpr}
{elseif testExpr}
{else}
{/if}
上述testExpr 是一個合法的javascript判定式
例子
引用內容{if customer != null && customer.balance > 1000}
We love you!
{/if}
{if user.karma > 100}
Welcome to the Black Sun.
{elseif user.isHero}
Sir, yes sir! Welcome!
{if user.lastName == "Yen"}
Fancy some apple pie, sir?
{/if}
{/if}
<a href="/login{if returnURL != null && returnURL != 'main'}?goto=${returnURL}{/if}">Login</a>
*JST引擎還包含一個輔助函數defined(str),這個可以測試一個變數是否已經被定義。
比如這段代碼判斷管理員發送了訊息給你
引用內容{if defined('adminMessage')}
System Administrator Important NOTICE: ${adminMessage}
{/if}
迴圈語句
引用內容{for varName in listExpr}
{/for}
{for varName in listExpr}
...main body of the loop...
{forelse}
...body when listExpr is null or listExpr.length is 0...
{/for}
*varName 必須是一個javascript的合法變數名
*listExpr 可以是一個數組,對象或者為空白,而且只能被賦值一次
例子
引用內容Two variables are bound in the main body of the loop:
__LIST__varName - holds the result of evaluating listExpr.
varName_index - this is the key or counter used during iteration.
Examples:
{for x in customer.getRecentOrders()}
${x_index} : ${x.orderNumber} <br/>
{forelse}
You have no recent orders.
{/for}
Converted pseudo-code for the above...
var __LIST__x = customer.getRecentOrders();
if (__LIST__x != null && __LIST__x.length > 0) {
for (var x_index in __LIST__x) {
var x = __LIST__x[x_index];
${x_index} : {$x.orderNumber} <br/>
}
} else {
You have no recent orders.
}
定義變數
引用內容{var varName}
{var varName = varInitExpr}
*varName必須是一個合法的javascript變數名
*varInitExpr必須是一個沒有包含"}"的字串
例子:
引用內容{var temp = crypto.generateRandomPrime(4096)}
Your prime is ${temp}.
宏定義
引用內容 {macro macroName(arg1, arg2, ...argN)}
...body of the macro...
{/macro}
*宏類似於一個javascript函數,不同點在於宏的主體是另外一個包含了諸如控制語句、迴圈語句的JST模板
*宏的名稱必須是一個合法javascript變數名
*宏的傳回值是一個字元創
*使用宏可以採用這種文法 :${macroName()}
一個使用宏的例子
引用內容{macro htmlList(list, optionalListType)}
{var listType = optionalListType != null ? optionalListType : "ul"}
<${listType}>
{for item in list}
<li>${item}</li>
{/for}
</${listType}>
{/macro}
Using the macro...
${htmlList([ 1, 2, 3])}
${htmlList([ "Purple State", "Blue State", "Red State" ], "ol")}
{var saved = htmlList([ 100, 200, 300 ])}
${saved} and ${saved}
運行上述語句將出現
引用內容*1
*2
*3
這樣的列表。只需將資料列表賦值給htmlList這個宏,就會幫你把資料通過<li>方式列出來,聰明的你很快就會把它改成<option><td>等應用了。
從宏的訪問域來說,預設情況下它是每個模板私人的,但是如果你想定義
一個宏庫的話,那麼也許你需要在process()之前先定義可以匯出宏:contextObject['exported'] ={};
下面是例子:
引用內容 {macro userName(user)}
{if user.aliasName != null && user.aliasName.length > 0}
${user.aliasName}
{else}
${user.login}
{/if}
{/macro}
${exported.userName = userName |eat}
另外,你也可以設定 contextObject['exported'] = contextObject;它也可以正常的工作。
CDATA 文本區段
[code]
{cdata}
...text emitted without JST processing...
{/cdata}
{cdata EOF}
...text emitted without JST processing...
EOF
未完待續,請查看原英文內容。。。
========================================================
下面的代碼是在查看163部落格代碼上看到的,有助於使用Trimpath--template
引用內容function createJST(jstId,jstContent){var textarea=document.createElement('textarea');textarea.value=jstContent;textarea.id=jstId;textarea.style.display='none';document.body.appendChild(textarea);}
function createJSTAndParse(jstId,jstContent){createJST(jstId,jstContent);return TrimPath.parseDOMTemplate(jstId);}
使用方法也就如下了:
引用內容var content = createJSTAndParse("HTML TemplateID","HTML TemplateContent").process({});