摘要:譯者說于年月日發布,該版本正式支持的關鍵字,并且用舊版本編譯同樣可以使用這兩個關鍵字,這無疑是一種進步。其次,這是最后一個支持和的版本了,在后續的版本了會移除對它們的兼容。
譯者說
Tornado 4.3于2015年11月6日發布,該版本正式支持Python3.5的async/await關鍵字,并且用舊版本CPython編譯Tornado同樣可以使用這兩個關鍵字,這無疑是一種進步。其次,這是最后一個支持Python2.6和Python3.2的版本了,在后續的版本了會移除對它們的兼容。現在網絡上還沒有Tornado4.3的中文文檔,所以為了讓更多的朋友能接觸并學習到它,我開始了這個翻譯項目,希望感興趣的小伙伴可以一起參與翻譯,項目地址是tornado-zh on Github,翻譯好的文檔在Read the Docs上直接可以看到。歡迎Issues or PR。
模板和UITornado 包含一個簡單,快速并靈活的模板語言. 本節介紹了語言以及相關的問題,比如國際化.
Tornado 也可以使用其他的Python模板語言, 雖然沒有準備把這些系統整合到 RequestHandler.render 里面. 而是簡單的將模板轉成字符串并傳遞給 RequestHandler.write
配置模板默認情況下, Tornado會在和當前.py文件相同的目錄查找關聯的模板文件. 如果想把你的模板文件放在不同的目錄中, 可以使用template_pathApplication setting (或復寫 RequestHandler.get_template_path 如果你不同的處理函數有不同的模板路徑).
為了從非文件系統位置加載模板, 實例化子類 tornado.template.BaseLoader并為其在應用設置(application setting)中配置template_loader.
默認情況下編譯出來的模板會被緩存; 為了關掉這個緩存也為了使(對目標的)修改在重新加載后總是可見, 使用應用設置(application settings)中的compiled_template_cache=False或debug=True.
模板語法一個Tornado模板僅僅是用一些標記把Python控制序列和表達式嵌入HTML(或者任意其他文本格式)的文件中:
{{ title }}
如果你把這個目標保存為"template.html"并且把它放在你Python文件的相同目錄下, 你可以使用下面的代碼渲染它:
class MainHandler(tornado.web.RequestHandler): def get(self): items = ["Item 1", "Item 2", "Item 3"] self.render("template.html", title="My title", items=items)
Tornado模板支持控制語句(control statements)和表達式(expressions).控制語句被包在{%和%}中間, 例如,{% if len(items) > 2 %}. 表達式被包在{{和}}之間, e.g.,{{ items[0] }}.
控制語句或多或少都和Python語句類似. 我們支持if,for,while, 和try, 這些都必須使用{% end %}來標識結束. 我們也支持 模板繼承(template inheritance) 使用extends和block標簽聲明, 這些內容的詳細信息都可以在 tornado.template 中看到.
表達式可以是任意的Python表達式, 包括函數調用. 模板代碼會在包含以下對象和函數的命名空間中執行 (注意這個列表適用于使用 RequestHandler.render
和RequestHandler.render_string渲染模板的情況. 如果你直接在RequestHandler之外使用tornado.template模塊, 下面這些很多都不存在).
escape: tornado.escape.xhtml_escape 的別名
xhtml_escape: tornado.escape.xhtml_escape 的別名
url_escape: tornado.escape.url_escape 的別名
json_encode: tornado.escape.json_encode 的別名
squeeze: tornado.escape.squeeze 的別名
linkify: tornado.escape.linkify 的別名
datetime: Python datetime 模塊
handler: 當前的 RequestHandler 對象
request: handler.request 的別名
current_user: handler.current_user 的別名
locale: handler.locale 的別名
_: handler.locale.translate 的別名
static_url: handler.static_url 的別名
xsrf_form_html: handler.xsrf_form_html 的別名
reverse_url: Application.reverse_url 的別名
所有從ui_methods和ui_modules`Application`設置的條目
任何傳遞給 RequestHandler.render 或RequestHandler.render_string 的關鍵字參數
當你正在構建一個真正的應用, 你可能想要使用Tornado模板的所有特性,尤其是目標繼承. 閱讀所有關于這些特性的介紹在 tornado.template部分 (一些特性, 包括UIModules是在 tornado.web 模塊中實現的)
在引擎下, Tornado模板被直接轉換為Python. 包含在你模板中的表達式會逐字的復制到一個代表你模板的Python函數中. 我們不會試圖阻止模板語言中的任何東西; 我們明確的創造一個高度靈活的模板系統, 而不是有嚴格限制的模板系統. 因此, 如果你在模板表達式中隨意填充(代碼), 當你執行它的時候你也會得到各種隨機錯誤.
所有模板輸出默認都會使用 tornado.escape.xhtml_escape 函數轉義.這個行為可以通過傳遞autoescape=None給 Application 或者tornado.template.Loader 構造器來全局改變, 對于一個模板文件可以使用{% autoescape None %}指令, 對于一個單一表達式可以使用{% raw ...%}來代替{{ ... }}. 此外, 在每個地方一個可選的轉義函數名可以被用來代替None.
注意, 雖然Tornado的自動轉義在預防XSS漏洞上是有幫助的, 但是它并不能勝任所有的情況. 在某一位置出現的表達式, 例如Javascript 或 CSS, 可能需要另外的轉義. 此外, 要么是必須注意總是在可能包含不可信內容的HTML中使用雙引號和 xhtml_escape , 要么必須在屬性中使用多帶帶的轉義函數(參見 e.g. http://wonko.com/post/html-escaping)
國際化當前用戶的區域設置(無論他們是否登錄)總是可以通過在請求處理程序中使用self.locale或者在模板中使用locale進行訪問. 區域的名字(e.g.,en_US) 可以通過locale.name獲得, 你可以翻譯字符串通過 Locale.translate 方法. 模板也有一個叫做_()全局函數用來進行字符串翻譯. 翻譯函數有兩種形式:
_("Translate this string")
是直接根據當前的區域設置進行翻譯, 還有:
_("A person liked this", "%(num)d people liked this", len(people)) % {"num": len(people)}
是可以根據第三個參數的值來翻譯字符串單復數的. 在上面的例子中,如果len(people)是1, 那么第一句翻譯將被返回, 其他情況第二句的翻譯將會返回.
翻譯最通用的模式四使用Python命名占位符變量(上面例子中的%(num)d) 因為占位符可以在翻譯時變化.
這是一個正確的國際化模板:
FriendFeed - {{ _("Sign in") }}
默認情況下, 我們通過用戶的瀏覽器發送的Accept-Language頭來發現用戶的區域設置. 如果我們沒有發現恰當的Accept-Language值, 我們會使用en_US. 如果你讓用戶進行自己偏愛的區域設置, 你可以通過復寫 RequestHandler.get_user_locale 來覆蓋默認選擇的區域:
class BaseHandler(tornado.web.RequestHandler): def get_current_user(self): user_id = self.get_secure_cookie("user") if not user_id: return None return self.backend.get_user_by_id(user_id) def get_user_locale(self): if "locale" not in self.current_user.prefs: # Use the Accept-Language header return None return self.current_user.prefs["locale"]
如果get_user_locale返回None,那我們(繼續)依靠Accept-Language頭(進行判斷).
tornado.locale 模塊支持兩種形式加載翻譯: 一種是用gettext和相關的工具的.mo格式, 還有一種是簡單的.csv格式.應用程序在啟動時通常會調用一次 tornado.locale.load_translations或者 tornado.locale.load_gettext_translations 其中之一; 查看這些方法來獲取更多有關支持格式的詳細信息..
你可以使用 tornado.locale.get_supported_locales() 得到你的應用所支持的區域(設置)列表. 用戶的區域是從被支持的區域中選擇距離最近的匹配得到的.例如, 如果用戶的區域是es_GT, 同時es區域是被支持的, 請求中的self.locale將會設置為es. 如果找不到距離最近的匹配項, 我們將會使用en_US.
UI 模塊Tornado支持UI modules使它易于支持標準, 在你的應用程序中復用UI組件. UI模塊像是特殊的函數調用來渲染你的頁面上的組件并且它們可以包裝自己的CSS和JavaScript.
例如, 如果你實現一個博客, 并且你想要有博客入口出現在首頁和每篇博客頁, 你可以實現一個Entry模塊來在這些頁面上渲染它們. 首先,為你的UI模塊新建一個Python模塊, e.g.,uimodules.py:
class Entry(tornado.web.UIModule): def render(self, entry, show_comments=False): return self.render_string( "module-entry.html", entry=entry, show_comments=show_comments)
在你的應用設置中, 使用ui_modules配置, 告訴Tornado使用uimodules.py:
from . import uimodules class HomeHandler(tornado.web.RequestHandler): def get(self): entries = self.db.query("SELECT * FROM entries ORDER BY date DESC") self.render("home.html", entries=entries) class EntryHandler(tornado.web.RequestHandler): def get(self, entry_id): entry = self.db.get("SELECT * FROM entries WHERE id = %s", entry_id) if not entry: raise tornado.web.HTTPError(404) self.render("entry.html", entry=entry) settings = { "ui_modules": uimodules, } application = tornado.web.Application([ (r"/", HomeHandler), (r"/entry/([0-9]+)", EntryHandler), ], **settings)
在一個模板中, 你可以使用{% module %}語法調用一個模塊. 例如,你可以調用Entry模塊從home.html:
{% for entry in entries %} {% module Entry(entry) %} {% end %}
和entry.html:
{% module Entry(entry, show_comments=True) %}
模塊可以包含自定義的CSS和JavaScript函數, 通過復寫embedded_css,embedded_javascript,javascript_files, 或css_files方法:
class Entry(tornado.web.UIModule): def embedded_css(self): return ".entry { margin-bottom: 1em; }" def render(self, entry, show_comments=False): return self.render_string( "module-entry.html", show_comments=show_comments)
模塊CSS和JavaScript將被加載(或包含)一次, 無論模塊在一個頁面上被使用多少次. CSS總是包含在頁面的標簽中, JavaScript 總是被包含在頁面最底部的標簽之前.
當不需要額外的Python代碼時, 一個模板文件本身可以作為一個模塊. 例如,先前的例子可以重寫到下面的module-entry.html:
{{ set_resources(embedded_css=".entry { margin-bottom: 1em; }") }}
這個被修改過的模塊模塊可以被引用:
{% module Template("module-entry.html", show_comments=True) %}
set_resources函數只能在模板中通過{% module Template(...) %}才可用. 不像{% include ... %}指令, 模板模塊有一個明確的命名空間它們的包含模板-它們只能看到全局模板命名空間和它們自己的關鍵字參數.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37722.html
摘要:譯者說于年月日發布,該版本正式支持的關鍵字,并且用舊版本編譯同樣可以使用這兩個關鍵字,這無疑是一種進步。其次,這是最后一個支持和的版本了,在后續的版本了會移除對它們的兼容。本節最好直接在或者閱讀,以獲得更好的閱讀體驗格式支持。 譯者說 Tornado 4.3于2015年11月6日發布,該版本正式支持Python3.5的async/await關鍵字,并且用舊版本CPython編譯Torn...
閱讀 1567·2021-11-24 09:39
閱讀 1054·2021-11-22 15:11
閱讀 2174·2021-11-19 11:35
閱讀 1630·2021-09-13 10:37
閱讀 2460·2021-09-03 10:47
閱讀 2147·2021-08-30 09:47
閱讀 1635·2021-08-20 09:39
閱讀 2907·2019-08-30 14:13