May 19, 2009
PHPとかerbのようなテンプレートをJavaScriptで。
UxU 0.5.11に入れ損ねた。次版で標準のヘルパーメソッドに入れるけど、割といいかげんな実装で、たいした規模じゃないから、テストケースの中に直接書いて使ってもいいと思う。
function parseTemplate(aCode, aContext) {
var __parseTemplate__codes = [];
aCode.split('%>').forEach(function(aPart) {
var strPart, codePart;
[strPart, codePart] = aPart.split('<%');
__parseTemplate__codes.push('__parseTemplate__results.push('+
strPart.toSource()+
');');
if (!codePart) return;
if (codePart.charAt(0) == '=') {
__parseTemplate__codes.push('__parseTemplate__results.push(('+
codePart.substring(1)+
') || "");');
}
else {
__parseTemplate__codes.push(codePart);
}
});
var __parseTemplate__results = [];
with(aContext|| {}) {
eval('(function() { '+__parseTemplate__codes.join('\n')+' }).call(aContext|| {})');
}
return __parseTemplate__results.join('');
}
var source = <![CDATA[
大切な事なので3回言います。
<% for (var i = 0; i < 3; i++) { %>
今日は<%= today %>です。
<% } %>
オーケー?
]]>.toString();
var params = {
today : (new Date()).toString()
};
var result = parseTemplate(source, params);
レガシーだけどクロスブラウザな書き方だったら、こうか。
function parseTemplate(aCode, aContext) {
var __parseTemplate__codes = [];
aCode = aCode.split('%>');
var strPart, codePart;
for (var i in aCode) {
aCode[i] = aCode[i].split('<%');
strPart = aCode[i][0];
codePart = aCode[i].length == 1 ? null : aCode[i][1] ;
__parseTemplate__codes.push('__parseTemplate__results.push(unescape("'+
escape(strPart)+
'"));');
if (!codePart) continue;
if (codePart.charAt(0) == '=') {
__parseTemplate__codes.push('__parseTemplate__results.push(('+
codePart.substring(1)+
') || "");');
}
else {
__parseTemplate__codes.push(codePart);
}
}
var __parseTemplate__results = [];
with(aContext|| {}) {
eval('(function() { '+__parseTemplate__codes.join('\n')+' }).call(aContext|| {})');
}
return __parseTemplate__results.join('');
}
var source = '大切な事なので3回言います。\n'+
'<% for (var i = 0; i < 3; i++) { %>\n'+
' 今日は<%= today %>です。\n'+
'<% } %>\n'+
'オーケー?';
var params = {
today : (new Date()).toString()
};
var result = parseTemplate(source, params);
wikieditish message: Ready to edit this entry.