【8/27まで】Udemyの人気コースが今なら1,200円から!!

【Tornado入門】template_pathパラメータとstatic_pathパラメータ

フォルダ構成

今回のフォルダ構成は以下のようになっています。

$ pwd; find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'
/c/Users/testuser/OneDrive/IT/Python/tornadoWebApp
|--server.py
|--static
|  |--css
|  |  |--modules    
|  |  |  |--mod1.css
|  |  |--style.css  
|  |--js
|  |  |--modules    
|  |  |  |--mod1.js 
|--template
|  |--index.html
|  |--modules
|  |  |--cook.html
|  |  |--cook2.html
|  |--result.html

サンプルソース

以下は、template_pathパラメータとstatic_pathパラメータを使用したサンプルです。
http://localhost:8888のGETリクエスト時、templateフォルダの中からindex.htmlを見つけて表示します。
http://localhost:8888/sousinのPOSTリクエスト時、templateフォルダの中からresult.htmlを見つけて表示します。

import os.path
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")
    
    def post(self):
        val1 = self.get_argument('name')
        val2 = self.get_argument('age')
        self.render("result.html",name=val1,age=val2)

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/sousin", MainHandler),
    ],
    template_path=os.path.join(os.path.dirname(__file__), 'template'),
    static_path=os.path.join(os.path.dirname(__file__), 'static')
)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

template_pathパラメータ

  • template_pathパラメータは、テンプレートファイルの場所をtornadoに教えます。 この記述をするとtemplateというフォルダからテンプレートファイルを見つけてくれるようになります。

static_pathパラメータ

  • static_pathパラメータは、css,js,画像など、静的コンテンツを保持するためにディレクトリのパスをtornadoに教えます。 html側では<link rel="stylesheet" href="{{static_url("style.css")}}">のように記述することでこれを利用できます。
  • static_urlは、ファイルの内容に基づいてハッシュを作り、これをURLの末尾に付与します。ハッシュがあることで、以前キャッシュされたバージョンではなく、常に最新のファイルをブラウザがダウンロードして利用することを保証します。
  • 静的コンテンツのフォルダを移動したくなったとしてもstatic_pathの参照先を修正するだけですべてのstatic_urlが自動的に参照先を変更してくれる。もし、static_urlを使わなかったら、すべてのテンプレートファイルを手修正する手間が生じる。

UIモジュール

  • UIモジュールは、アプリケーション全体で再利用可能なコンポーネントです。
  • UIモジュールが呼び出されたときにだけ適用したいCSSやJavaScriptがある場合、embedded_cssembedded_javascriptを利用します。

server.py

以下はPythonコードです。

import os.path
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):

        cook1 = {"title":"焼肉","impression":"最高!"}
        cook2 = {"title":"ラーメン","impression":"超最高!"}
        cook3 = {"title":"寿司","impression":"メチャ最高!!"}
        cookList = [cook1, cook2, cook3]

        self.render("index.html", cookList=cookList)

class CookModules(tornado.web.UIModule):
    def render(self,cook):
        return self.render_string('modules/cook.html',cook=cook)

    def css_files(self):
        return 'css/modules/mod1.css'

    def javascript_files(self):
        return 'js/modules/mod1.js'

application = tornado.web.Application([
    (r"/", MainHandler)
],
    template_path=os.path.join(os.path.dirname(__file__), 'template'),
    static_path=os.path.join(os.path.dirname(__file__), 'static'),
    ui_modules={'CookUI':CookModules}
)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

index.html

以下はブラウザに表示するHTMLページです。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>UIModulesTestPage</title>
<script type="text/javascript"></script>
<link rel="stylesheet" href="{{static_url("css/style.css")}}">
</head>
<body>
    {% for cook in cookList %}
    {% module CookUI(cook) %}
    {% end %}
</body>
</html>

cook.html

以下はモジュール用HTMLページです。

<div class="cook_box">
    <h2 class="cook_title">{{cook["title"]}}</h2>
    <p>{{cook["impression"]}}</p>
</div>

コード解説

  • ブラウザでhttp://localhost:8888にアクセスします。
    このとき、server.pyの以下のコードが処理され、cookListをindex.htmlに渡します。
    class MainHandler(tornado.web.RequestHandler):
    def get(self):
    
        cook1 = {"title":"焼肉","impression":"最高!"}
        cook2 = {"title":"ラーメン","impression":"超最高!"}
        cook3 = {"title":"寿司","impression":"メチャ最高!!"}
        cookList = [cook1, cook2, cook3]
    
        self.render("index.html", cookList=cookList)
    
  • index.html側では以下のコードが処理され、cookListの内容を一つづつcookに格納し、{% module CookUI(cook) %}の部分で、UIモジュールを呼び出しています。
    このコードでは、CookUIというUIモジュールにcookを渡しています。
    <body>
        {% for cook in cookList %}
        {% module CookUI(cook) %}
        {% end %}
    </body>
    
  • CookUIというはserver.pyの以下のコードに書かれています。このコードはCookUIというモジュールがCookModulesクラスを呼び出すことを意味しています。
    ui_modules={'CookUI':CookModules}
    
  • CookModulesクラスは、server.pyで以下のように記述しています。
    このコードは、index.htmlから受け取ったcookをmodulesフォルダ配下に格納されているcook.htmlに渡しています。
    class CookModules(tornado.web.UIModule):
        def render(self,cook):
            return self.render_string('modules/cook.html',cook=cook)
    
        def css_files(self):
            return 'css/modules/mod1.css'
    
        def javascript_files(self):
            return 'js/modules/mod1.js'
    
  • cook.htmlは以下のように記述しています。{{cook["title"]}}の部分でtitleを表示し、{{cook["impression"]}}の部分でimpressionを表示しています。
    <div class="cook_box">
        <h2 class="cook_title">{{cook["title"]}}</h2>
        <p>{{cook["impression"]}}</p>
    </div>
    

static_pathパラメータを設定している場合は、そこが基点パスになります。

コメントを残す

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