jQueryテンプレートエンジンを改良してみた

こないだ作ったjquery.jsontpl.jsを改良してみた。

プレースホルダーとして<var class="Foo"></var>などと記述すると変数Fooの値で置換される。または、class=".Foo.jsontpl-var"な任意の要素のinnerHTMLに変数Fooの値が設定される。みたいな仕様。

index.html

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
    <title>jQuery Template</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <script src="./common/js/jquery.1.5.js" type="text/javascript"></script>
    <script src="./common/js/jquery.jsontpl.js" type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[
        $(document).ready(function(){
            // set global params
            jQuery.jsontpl.setParams({classPrefix:'jsontpl'});

            // jQueryエレメントをテンプレートとして使用
            $.jsontpl.parse($('#templates tr'),'./data.json').appendTo('.movie');

            // jQueryエレメントをテンプレートとして使用(別パターン)
            $.jsontpl('#templates tr').parse('./data.json').appendTo('.movie');

            // テンプレートとJSONをサーバーから取得
            $.jsontpl.parse('./tpl.html','./data.json').appendTo('.movie');

            // テンプレートのみサーバーから取得
            var json = {
                "Name": "test1",
                "ReleaseYear": "test2",
                "Director": "test3"
            };
            $.jsontpl.parse('./tpl.html', json).appendTo('.movie');

            // テンプレートとJSONをサーバーから取得
            $.jsontpl.getTpl('./tpl.html').parse('./data.json').appendTo('.movie');
        });
    //]]>
    </script>
</head>

<body>
    <div id="templates" style="display:none;">
        <table>
            <tr><!-- template -->
                <th class="Name jsontpl-var"></th>
                <td class="ReleaseYear jsontpl-var"></td>
                <td class="Director jsontpl-var"></td>
                <td class="conbination">
                    <!-- placeholer not required -->
                    <var class="Name"></var>
                    <var class="ReleaseYear"></var>
                </td>
            </tr>
        </table>
    </div>
    <table class="movie" summary="summary">
    </table>
</body>
</html>

data.json

[
{ "Name": "The Red Violin", "ReleaseYear": "1998", "Director": "Francois Girard" },
{ "Name": "Eyes Wide Shut", "ReleaseYear": "1999", "Director": "Stanley Kubrick" },
{ "Name": "The Inheritance", "ReleaseYear": "1976", "Director": "Mauro Bolognini" }
]

結果

下記のようになります。

<table summary="summary" class="movie">
    <tbody><tr><!-- template -->
                <th class="Name">The Red Violin</th>
                <td class="ReleaseYear">1998</td>
                <td class="Director">Francois Girard</td>
                <td class="conbination">
                    <!-- placeholer not required -->
                    The Red Violin
                    1998
                </td>
            </tr><tr><!-- template -->
                <th class="Name">Eyes Wide Shut</th>
                <td class="ReleaseYear">1999</td>
                <td class="Director">Stanley Kubrick</td>
                <td class="conbination">
                    <!-- placeholer not required -->
                    Eyes Wide Shut
                    1999
                </td>
            </tr><tr><!-- template -->
                <th class="Name">The Inheritance</th>
                <td class="ReleaseYear">1976</td>
                <td class="Director">Mauro Bolognini</td>
                <td class="conbination">
                    <!-- placeholer not required -->
                    The Inheritance
                    1976
                </td>
            </tr><tr><!-- template -->
                <th class="Name">The Red Violin</th>
                <td class="ReleaseYear">1998</td>
                <td class="Director">Francois Girard</td>
                <td class="conbination">
                    <!-- placeholer not required -->
                    The Red Violin
                    1998
                </td>
            </tr><tr><!-- template -->
                <th class="Name">Eyes Wide Shut</th>
                <td class="ReleaseYear">1999</td>
                <td class="Director">Stanley Kubrick</td>
                <td class="conbination">
                    <!-- placeholer not required -->
                    Eyes Wide Shut
                    1999
                </td>
            </tr><tr><!-- template -->
                <th class="Name">The Inheritance</th>
                <td class="ReleaseYear">1976</td>
                <td class="Director">Mauro Bolognini</td>
                <td class="conbination">
                    <!-- placeholer not required -->
                    The Inheritance
                    1976
                </td>
            </tr><tr>
    <th class="Name">The Red Violin</th>
    <td class="ReleaseYear">1998</td>
    <td class="Director">Francois Girard</td>
    <td class="conbination">
        <!-- placeholer not required -->
        The Red Violin
        1998
    </td>
</tr><tr>
    <th class="Name">Eyes Wide Shut</th>
    <td class="ReleaseYear">1999</td>
    <td class="Director">Stanley Kubrick</td>
    <td class="conbination">
        <!-- placeholer not required -->
        Eyes Wide Shut
        1999
    </td>
</tr><tr>
    <th class="Name">The Inheritance</th>
    <td class="ReleaseYear">1976</td>
    <td class="Director">Mauro Bolognini</td>
    <td class="conbination">
        <!-- placeholer not required -->
        The Inheritance
        1976
    </td>
</tr><tr>
    <th class="Name">test1</th>
    <td class="ReleaseYear">test2</td>
    <td class="Director">test3</td>
    <td class="conbination">
        <!-- placeholer not required -->
        test1
        test2
    </td>
</tr><tr>
    <th class="Name">The Red Violin</th>
    <td class="ReleaseYear">1998</td>
    <td class="Director">Francois Girard</td>
    <td class="conbination">
        <!-- placeholer not required -->
        The Red Violin
        1998
    </td>
</tr><tr>
    <th class="Name">Eyes Wide Shut</th>
    <td class="ReleaseYear">1999</td>
    <td class="Director">Stanley Kubrick</td>
    <td class="conbination">
        <!-- placeholer not required -->
        Eyes Wide Shut
        1999
    </td>
</tr><tr>
    <th class="Name">The Inheritance</th>
    <td class="ReleaseYear">1976</td>
    <td class="Director">Mauro Bolognini</td>
    <td class="conbination">
        <!-- placeholer not required -->
        The Inheritance
        1976
    </td>
</tr></tbody></table>

jquery.jsontpl.js

/*!
 * jquery.jsontpl - client side template engine powered by jQuery
 *
 * @requires jQuery version 1.5 or higher
 * @version 0.0.2
 */
(function ($) {

    $.jsontpl = $.subclass();

    /**
     * debug console for plugin develop
     */
    var console = {
        log : (window.console) ? window.console.log : function () {}
    };

    /**
     * default params
     */
    $.jsontpl.params = {
        classPrefix : 'jsontpl',
        __trailing__: null
    };

    /**
     * Override params
     *
     * @param obj {object}
     * @returns {jQuery.jsontpl}
     */
    $.jsontpl.setParams = function (params) {
        $.extend($.jsontpl.params, params);
        return this;
    };

    /**
     * ajax cache {url : data}
     */
    var cache = {};

    /**
     * modified $.ajax for cache mechanism
     *
     * @param params {object}
     * @returns {XMLHttpRequest | empty object}
     */
    $.jsontpl.ajax = function (params) {
        if (cache[params.url]) {
            params.success(cache[params.url]);
            return {};
        }
        params.success = (function() {
            var url = params.url;
            var orgSuccess = params.success;
            return function(a) {
                cache[url] = a;
                orgSuccess(a);
            }
        })();
        return $.ajax(params);
    };

    /**
     * $.ajax wrapper for template get
     *
     * @param url {string}
     * @returns {jQuery.jsontpl}
     */
    $.jsontpl.getTpl = function (url) {
        var ret;
        $.jsontpl.ajax({
            type: "GET",
            url: url,
            cache: true,
            async: false,
            error: function (error) {
                console.log(error.statusText + " at " + url);
            },
            success: function (tpl) {
                ret = $.jsontpl(tpl);
            }
        });
        return ret;
    };

    /**
     * $.ajax wrapper for JSON get
     *
     * @param url {string}
     * @returns {jQuery.jsontpl}
     */
    $.jsontpl.getJSON = function (url) {
        var ret;
        $.jsontpl.ajax({
            type: "GET",
            url: url,
            cache: true,
            async: false,
            dataType: 'json',
            error: function (error) {
                console.log(error.statusText + " at " + url);
            },
            success: function (json) {
                ret = json;
            }
        });
        return ret;
    };

    /**
     * $.ajax wrapper for getting tpl & json
     *
     * @param tpl {string} template filename
     * @param json {string} json filename
     * @returns {jQuery.jsontpl} template & json
     */
    $.jsontpl.get = function (tpl, json) {
        return {
            tpl  : $.jsontpl.getTpl(tpl),
            json : $.jsontpl.getJSON(json)
        };
    };

    /**
     * Parse template
     *
     * @param tpl {jQuery element | string} jQuery element or filename
     * @param json {object | string} object or filename
     * @returns {jQuery element}
     */
    var _parse =  function (tpl, json) {
        if (typeof tpl === 'string') {
            tpl = $.jsontpl.getTpl(tpl);
        }
        if (typeof json === 'string') {
            json = $.jsontpl.getJSON(json);
        } else if ((json.constructor !== Array)) {
            json = [json];
        }
        var ret = $('<div></div>');
        for (var obj in json) {
            var a = tpl.clone();
            for (var tplvar in json[obj]) {

                // replace <var>
                a.find("var." + tplvar).after(json[obj][tplvar]).remove();

                // replace innerHTML of class *.placeholder
                var placeholder = $.jsontpl.params.classPrefix + '-var';
                a.find("." + placeholder + "." + tplvar)
                    .html(json[obj][tplvar])
                    .removeClass(placeholder);
            }
            ret.append(a);
        }
        return $.jsontpl(ret.html());
    };

    /**
     * Parse template
     *
     * @param tpl {jQuery element | string} jQuery element or filename
     * @param json {object | string} object or filename
     * @returns {jQuery element}
     */
    $.jsontpl.parse = _parse;

    /**
     * Parse template
     *
     * @param json {object | string} object or filename
     * @returns {jQuery.jsontpl element}
     */
    $.jsontpl.fn.parse = function (json) {
        return _parse(this, json);
    };
})(jQuery);

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です