白話 Tornado 原始碼(5):褪去模板的外衣

發表於2015-09-17

上一篇《白話tornado原始碼(3):請求來了》介紹了客戶端請求在tornado框架中的生命週期,其本質就是利用epoll和socket來獲取並處理請求。在上一篇的內容中,我們只是給客戶端返回了簡單的字串,如:“Hello World”,而在實際開發中,需要使用html檔案的內容作為模板,然後將被處理後的資料(計算或資料庫中的資料)巢狀在模板中,然後將巢狀了資料的html檔案的內容返回給請求者客戶端,本篇就來詳細的剖析模板處理的整個過程。

概述

 (配圖超大,請點選這裡看大圖

上圖是返回給使用者一個html檔案的整個流程,較之前的Demo多了綠色流線的步驟,其實就是把【self.write(‘hello world’)】變成了【self.render(‘main.html’)】,對於所有的綠色流線只做了五件事:

  • 使用內建的open函式讀取Html檔案中的內容
  • 根據模板語言的標籤分割Html檔案的內容,例如:{{}} 或 {%%}
  • 將分割後的部分資料塊格式化成特殊的字串(表示式)
  • 通過python的內建函式執行字串表示式,即:將html檔案的內容和巢狀的資料整合
  • 將資料返回給請求客戶端

所以,如果要返回給客戶端對於一個html檔案來說,根據上述的5個階段其內容的變化過程應該是這樣:




在第4步中,執行第3步生成的字串表示的函式後得到的返回值就是要返回給客戶端的響應資訊主要內容。

3.13、RequestHandler的render方法

此段程式碼主要有三項任務:

  • 獲取Html檔案內容並把資料(程式資料或框架自帶資料)巢狀在內容中的指定標籤中(本篇主題)
  • 執行ui_modules,再次在html中插入內容,例:head,js檔案、js內容、css檔案、css內容和body
  • 內部呼叫客戶端socket,將處理請求後的資料返回給請求客戶端

對於上述三項任務,第一項是模板語言的重中之重,讀取html檔案並將資料巢狀到指定標籤中,以下的步驟用於剖析整個過程(詳情見下文);第二項是對返會給使用者內容的補充,也就是在第一項處理完成之後,利用ui_modules再次在html中插入內容(head,js檔案、js內容、css檔案、css內容和body);第三項是通過socket將內容響應給客戶端(見上篇)。

對於ui_modules,每一個ui_module其實就是一個類,一旦註冊並啟用了該ui_module,tornado便會自動執行其中的方法:embedded_javascript、javascript_files、embedded_css、css_files、html_head、html_body和render ,從而實現對html內容的補充。(執行過程見上述程式碼)

自定義UI Modules

此處是一個完整的 建立 –> 註冊 –> 啟用 的Demo

目錄結構:

├── index.py
├── static
└── views
└── index.html


3.13.1~6、RequestHandler的render_string方法

該方法是本篇的重中之重,它負責去處理Html模板並返回最終結果,【概述】中提到的5件事中前四件都是此方法來完成的,即:

  1. 建立Loader物件,並執行load方法
    — 通過open函式開啟html檔案並讀取內容,並將內容作為引數又建立一個 Template 物件
    — 當執行Template的 __init__ 方法時,根據模板語言的標籤 {{}}、{%%}等分割並html檔案,最後生成一個字串表示的函式
  2. 獲取所有要嵌入到html模板中的變數,包括:使用者返回和框架預設
  3. 執行Template物件的generate方法
    — 編譯字串表示的函式,並將使用者定義的值和框架預設的值作為全域性變數
    — 執行被編譯的函式獲取被巢狀了資料的內容,然後將內容返回(用於響應給請求客戶端)

注意:詳細編譯和執行Demo請參見《第四篇:白話tornado原始碼之褪去模板外衣的前戲 》





其中涉及的類有:




so,上述整個過程其實就是將一個html轉換成一個函式,併為該函式提供全域性變數,然後執行該函式!!

  

結束語

上述就是對於模板語言的整個流程,其本質就是處理html檔案內容將html檔案內容轉換成函式,然後為該函式提供全域性變數環境(即:我們想要巢狀進html中的值和框架自帶的值),再之後執行該函式從而獲取到處理後的結果,再再之後則執行UI_Modules繼續豐富返回結果,例如:新增js檔案、新增js內容塊、新增css檔案、新增css內容塊、在body內容第一行插入資料、在body內容最後一樣插入資料,最終,通過soekct客戶端物件將處理之後的返回結果(字串)響應給請求使用者。

相關文章