TMLib.js Tips – format 関数を使って html の簡易テンプレートを作ろう!!

phiary に引っ越しました. 毎日プログラミングやWebに関する情報を発信しています! RSS 登録してたまに覗いたり, tweet やハテブして拡散してもらえると幸いです.

Pocket

tmlib.js の String.prototype.format を使って html の簡易テンプレートを作ってみました.(tmlib.jsとは?)

html でブログやイメージギャラリーなんかをつくる際, 同じようなタグ構造を繰り返し使うことがあると思います. そんなときに使えるのが今回の tips です.

一部の内容をパラメータ化して, 後で javascript で内容を差し替えることで html とデータを分離することができます. うまく説明できてないかな? とりあえずサンプルを見てみてください. 結構便利ですよ♪

Sample and Download

今回制作したサンプルはこちら.

ダウンロードはこちらからできます.

Code

今回制作したサンプル全体のコードです. body タグ内がスッキリしているのが分かるかと思います. 項目を増やしたい時は単純に data 内のオブジェクトを増やすだけで済んじゃいます.

<!DOCTYPE html> 
<html lang="ja"> 
    <head> 
        <meta charset="utf-8"> 
        <title>Templating with JavaScript</title>
        <style>
            * {
                -webkit-box-sizing: border-box;
                -moz-box-sizing: border-box;
                -o-box-sizing: border-box;
                box-sizing: border-box;
                font-family: "Meiryo", Arial, Helvetica, sans-serif;
                line-height: 1.5em;
            }
            body {
                font-size: 14px;
            }
        </style>
        <script type="text/javascript" src="./../../src/tmlib.js"></script>
        <script>
            // データ部分
            var data = [
                {
                    title   : "Shooting",
                    link    : "http://tmlib-js.googlecode.com/svn/trunk/tutorial/shooting/index.html",
                    img     : "https://lh6.googleusercontent.com/-0saDLhKo7IU/TwbTF8-c7VI/AAAAAAAAAVQ/LJLPtlUH920/s950/shooting.jpg",
                    alt     : "シューティングサンプル",
                },
                {
                    title   : "Paint",
                    link    : "http://tmlib-js.googlecode.com/svn/trunk/tutorial/paint/index.html",
                    img     : "https://lh6.googleusercontent.com/-_2Qq96rZ0gE/TwbTYb_qcpI/AAAAAAAAAVY/dYKub9ThSJQ/s950/paint.jpg",
                    alt     : "ペイントサンプル",
                },
                {
                    title   : "Circle Collision",
                    link    : "http://tmlib-js.googlecode.com/svn/trunk/samples/circle-collision/index.html",
                    img     : "https://lh5.googleusercontent.com/-gsm3vtz3rDQ/TwbP4mHU6UI/AAAAAAAAAUU/hIYPZ2k4Dts/s950/circle-collision.jpg",
                    alt     : "サークルの衝突サンプル",
                },
                {
                    title   : "Unit Circle",
                    link    : "http://tmlib-js.googlecode.com/svn/trunk/samples/unit-circle/index.html",
                    img     : "https://lh3.googleusercontent.com/-683pfzSF4KU/TwbR12b9RfI/AAAAAAAAAVA/5Wj5g6J1PHE/s950/unit-circle.jpg",
                    alt     : "単位円サンプル",
                },
            ];
            
            /**
             * メイン処理
             */
            TM.main(function(){
                // 結果を代入
                var eResult   = TM.$id("result");
                var eTemplate = TM.$id("template");
                eResult.innerHTML = formatTemplate(eTemplate.innerHTML, data);
            });
            
            /**
             * テンプレートをフォーマット
             * {...} を data で置き換える.
             */
            var formatTemplate = function(template, data) {
                var result = "";
                
                for (var i=0,len=data.length; i<len; ++i) {
                    result += template.format(data&#91;i&#93;);
                }
                
                return result;
            };
            
        </script>
    </head>
    
    <body>
        <h1>Templating with JavaScript</h1>
        <p>
            javascript でテンプレート化してみました. format の活用例です.
        </p>
        <div id="result">
            ここに結果が入ります.
        </div>
        
        <!-- &#91;template start&#93; -->
        <script type="template" id="template">
            <section>
                <h2><a href="{link}">{title}</a></h2>
                <p>
                    <img alt="{alt}" src="{img}" width="300" border="1" />
                </p>
            </section>
        </script>
        <!-- &#91;template end&#93; -->
    </body>
</html>

Tips

String.prototype.format とは

String.prototype.format は, tmlib.js で定義されている関数で下記のように {...} を引数の内容で置換してくれる関数です.

document.write("{0} + {1} = {2}".format(5, 10, 5+10));   // "5 + 10 = 15"
document.write("rgb({r}, {g}, {b})".format({             // "rgb(128, 0, 255)"
    r: 128,
    g: 0,
    b: 255
}));

テンプレートを定義しよう!

script タグで type 属性に text/javascript 以外を指定すると javascript としてパースされずに無視されるので ブラウザ上で認識されない文字列群として使用することができます.

今回はその仕組を利用して script タグ内に template を定義しています. この中の {...}内にある文字列がデータのパラメータになります.

<!-- &#91;template start&#93; -->
<script type="template" id="template">
    <section>
        <h2><a href="{link}">{title}</a></h2>
        <p>
            <img alt="{alt}" src="{img}" width="300" border="1" />
        </p>
    </section>
</script>
<!-- &#91;template end&#93; -->

String.prototype.format でテンプレートを置換しながら生成しよう

これが今回のエントリーのキモです.

下記の関数は data 内にあるオブジェクトの数だけ template を置換しながら生成しています.

var formatTemplate = function(template, data) {
    var result = "";
    
    for (var i=0,len=data.length; i<len; ++i) {
        result += template.format(data&#91;i&#93;);
    }
    
    return result;
};
&#91;/code&#93;</pre>
        <p>
            やってることは, template 内の文字列を, <strong>{...}を data で置換しながら</strong>生成して連結しています.
            そして最後に結果の文字列を結果用に用意した要素の innerHTML に代入することでテンプレート化を実現しています.
        </p>
        
        <pre class="prettyprint">
TM.main(function(){
    // 結果を代入
    var eResult   = TM.$id("result");
    var eTemplate = TM.$id("template");
    eResult.innerHTML = formatTemplate(eTemplate.innerHTML, data);
});

Reference

元ネタのサイトです.

実装(ここではhtml?)とデータを分離ってのはゲームプログラミングでは基本だったりするんですが, html だと結構違和感というか物珍しい感じがありますね.

こんな感じで tmlib.js の活用例をじゃんじゃん紹介していきます.

TRACK BACK URL

POST COMMENT

メールアドレスが公開されることはありません。

COMMENT