pythonでテンプレート自作 (json読み込みからhtml出力)

ヒアドキュメントとreplace

ヒアドキュメントとreplaceの合わせ技で特定のキーワードに対して必要なデータに変換してぶっこむことが出来る。 たとえば

 s = """hello {name}!""".replace("{name}", "hoge")

のようにじっこうすると{name}の部分がhogeに変換される。
hello hoge!

このようにやれば正規表現知らなくても特定のキーワードさえ決めてしまえば変換して流し込める。jsonを読み込んで、htmlに流し込むことも可能。もちろん、ajax使ってjavascriptでやってもいいけどね。

test.json

{
    "user_data": {
        "#": "ユーザデータ", 
        "id": "int(11) id", 
        "name": "varchar(256) ユーザー名",
        "description": "varchar(256) 説明", 
        "update_time": "datetime 更新日時", 
        "create_time": "datetime 作成日時"
    }, 
    "stone_data": {
        "#": "ストーンデータ", 
        "id": "int(11) id", 
        "name": "varchar(256) 販売表示名称 ", 
        "limit_count": "int(11) 上限回数", 
        "description": "varchar(256) 説明", 
        "update_time": "datetime 更新日時", 
        "create_time": "datetime 作成日時"
    }
}

test.py

# -*- coding: utf-8 -*-
import sys
import json

def html_src():
    return """
<html>

<head>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <meta charset="utf-8">
</head>

<body>
    <style>
        .in { display: inline; padding-left: 1em; }
    </style>

    <input type="text" id="text"><br>
    <content id="content">
    {html_template}
    </content>

<!-- logic -->
    <script>
    var onToggle = function() {
        var id = "#" + $(this).attr("name");
        if ($(id).is(":visible")) {
            $(id).hide();
        } else {
            $(id).show();
        }
    };
    $(document).ready(function() {
        var changeVisible = function(elem, flag) {
            if (flag) {
                elem.show();
            } else {
                elem.hide();
            }
        };
        var changeText = function() {
            str = $(this).val();
            strs = str.split(" ");
            $("#content > div > h2").each(function() {
                var visible = true;
                for(var i = 0; i < strs.length; ++i) {
                    var name = $(this).html();
                    if (name.indexOf(strs[i]) === -1) {
                      visible = false;
                      break;
                    }
                }
                var id = "#" + name.split(" ")[0] + "-table";
                changeVisible($(id), visible);
            });
        };
        $("#text").each(function() {
            $(this).bind("keyup", changeText);
        }); 

        {js_template}
    });
    </script>
</body>
</html>
    """

def table_template(table_str, comment_str, list_hash):
    list_template = ""
    for k, v in list_hash.items():
        list_template += "<li>{0} - {1}</li>".format(k.encode('utf_8'), v.encode('utf_8'))

    template = """
    <div id="{table}-table">
        <button id="{table}-button" name="{table}">on</button>
        <h2 class="in">{table} #{comment}</h2><br>
        <div id={table}>
        <ul>
            {list}
        </ul>
        </div>
    </div>
    """.replace("{table}", table_str.encode('utf_8')).replace("{comment}", comment_str.encode('utf_8')).replace("{list}", list_template)
    return template

def read_json(path):
    f = open(path, 'r')
    json_data = json.load(f)
    f.close()
    return json_data

if __name__ == '__main__':
    json_data = read_json('test.json')

    html_tables = ""
    for k, v in json_data.items():
        table_name = k
        comment = v.pop("#")
        list = v
        html_tables += table_template(table_name, comment, list)

    js_tables = ""
    for k,v in json_data.items():
        table_name = k
        js_tables += """
            $("#{0}-button").on("click", onToggle);
            $("#{0}").hide();
        """.replace("{0}", table_name)

    t = html_src()
    new_html = t.replace("{html_template}", html_tables).replace("{js_template}", js_tables.encode('utf_8'))
    f = open("test.html", "w")
    f.write(new_html)
    f.close()