404 motivation not found | t_ishidaのブログ

5月/08

27

テンプレートエンジンもどき

能書き

必要が有って作ってみた。昔作った定期メール送信用のテンプレートエンジンもどきに手を加えて、

HTML::Templateライクにしてみた。

まだ実用はしてない。テストもろくたらしてない。

使っても良いけど、何が有っても知らん。JScriptでしか試してない。

書き方とかはHTML::Tepmlateの不便な奴だと思って。テストして駄目なら修正してここに反映する。

追記1

テストデータを使っただけの簡単な動作確認なら、FireFox,IE共に動いてるっぽいです。

追記2

簡単なテンプレートのパースだけですが、実用してます。

追記3

なんか、はてぶ1件されてるとか本当に読んでいる人がいるっぽいので説明しとくと、

  • EXPR=で使える引用符はシングルクォートのみ
  • TMPL_IFとかTMPL_LOOPは一行にひとつのみ
  • TMPL_IFとかTMPL_LOOPのある行は、それしか存在しないはずと言う想定

と、かなり雑な作りです。(何せ僕しか使わないと思ってるので)

要望があれば、書いてくれれば対応するかも知れません。

追記4

2008/07/09

機能アップとか色々したのを反映。

都度直しているせいで、t_ishida的、長い一行的なのが増えてきた^^;

var data  = {
x : [
{ val : 1, y : [ { Z : 'abc' } ] },
{ val : 2, y : [ { Z : 'def' } ] },
{ val : 3, y : [ { Z : 'ghi' } ] },
{ val : 4, y : [ { Z : 'jkl' } ] },
{ val : 5, y : [ { Z : 'mno' } ] },
{ val : 6, y : [ { Z : 'pqr' } ] }
]
};
var test_data = "";
test_data += "<TMPL_LOOP EXPR='x'>\r\n";
test_data += "	<TMPL_IF EXPR='val == 3'>\r\n";
test_data += "	<p><TMPL_VAL EXPR='val'>ふがふが</p>\r\n";
test_data += "  <TMPL_ELSE>\r\n";
test_data += "	<p><TMPL_VAL EXPR='val'>ほげほげ</p>\r\n";
test_data += "  <TMPL_LOOP EXPR='y'>\r\n";
test_data += "    <p><TMPL_VAL EXPR='Z'></p>\r\n";
test_data += "  </TMPL_LOOP>\r\n";
test_data += "  </TMPL_IF>\r\n";
test_data += "</TMPL_LOOP>\r\n";

WScript.Echo( parseTemplate( test_data, data ) );
function parseTemplate ( template, data ){
var lines = template.split( /(\r\n|\r|\n)/ );
for(var i = 0, l = lines.length; i < l; i++ ){
var ln = lines[i];
if( ln == '' ) continue;
ln = ln.replace( /\s+$/, '');
if( ln.match(/<TMPL_VAL/ ) ) {
ln = "body += '" + ln.replace(/(['"])/g, "\\$1" ) + "\\r\\n';";
while( true ){
if( !ln.match(/<TMPL_VAL +EXPR *= *\\["']([^"']+)\\["'](?: +LIMIT *= *\\'(.+?)\\')?(?: +STRIP_TAGS *= *\\'(.+?)\\')?/ ) ) break;
var nm  = "data." + RegExp.$1 ,len = RegExp.$2, tag = RegExp.$3;
var tmp = len ? ("' + (" + nm + ".toString().length > " + len + " ? " + nm + ".toString().substr( 0, " + len + " ) + '...' : " + nm + ") + '") : ("' + " + nm + " + '");
if( tag ) tmp = tmp.replace( new RegExp( nm, 'g' ), nm + ".replace(/<.*?>/g,'')" );
ln = ln.replace( /<TMPL_VAL.+?>/, tmp );
}
} else if( ln.match( /<\/?TMPL_[^\>]+>/ ) ){
ln = ln.replace( /<\/TMPL_IF>/g, '}' )
.replace( /<\/TMPL_LOOP>/g, '}\ndata_bk.pop();data=data_bk[data_bk.length - 1];i.pop();' )
.replace( /<TMPL_ELSE>/g, "} else {" )
.replace( /<TMPL_IF EXPR *= *'(\S+) *(==|<|>|<=|>=)? *(\S+)? *'>/g, "if( data.$1 $2 $3) {" );
if( ln.match( /<TMPL_LOOP EXPR *= *'(.+?)'(?: +LIMIT *= *'(.+?)')?/ ) )
ln = ln.replace( /<TMPL_LOOP EXPR *= *'(.+?)'.*?>/, "data_bk.push( data.$1 );\n i.push(0); \n" +
"for( i[i.length-1] = 0; i[i.length-1] < data_bk[data_bk.length-1].length; i[i.length-1]++ ){ \n" +
"data = data_bk[data_bk.length-1][i[i.length-1]];" +
( RegExp.$2 ?  'if( i[i.length-1] >= ' + RegExp.$2 + ' ) break;' : '' )
);
ln = ln.replace(/(['"])/g,'\\$1');
} else {
ln = "body += '" + ln.replace(/(['"])/g,'\\$1') + "\\r\\n';\r\n";
}
if( ln.match(/<\/?TMPL_/) ) alert( i + '行目:パース出来てない:' + ln );
lines[i] = ln;
}
var body = '', data_bk = [], i = [];
data_bk.push( data );
//    if( document.getElementById('debug') ) document.getElementById('debug').value = lines.join( "\r\n" );
eval( lines.join( "\r\n" ) );
return body;
}
Share and Enjoy:
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Tumblr
  • email
  • Facebook
  • FriendFeed

RSS Feed

コメントはまだありません。

Leave a comment!

<< PHPでRESTな感じのエンティティ実装方法の模索

Perlの書籍案内 >>

Find it!

Theme Design by devolux.org

Tag Cloud