摘要:譯者說于年月日發(fā)布,該版本正式支持的關(guān)鍵字,并且用舊版本編譯同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次,這是最后一個支持和的版本了,在后續(xù)的版本了會移除對它們的兼容。
譯者說
Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5的async/await關(guān)鍵字,并且用舊版本CPython編譯Tornado同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次,這是最后一個支持Python2.6和Python3.2的版本了,在后續(xù)的版本了會移除對它們的兼容?,F(xiàn)在網(wǎng)絡(luò)上還沒有Tornado4.3的中文文檔,所以為了讓更多的朋友能接觸并學習到它,我開始了這個翻譯項目,希望感興趣的小伙伴可以一起參與翻譯,項目地址是tornado-zh on Github,翻譯好的文檔在Read the Docs上直接可以看到。歡迎Issues or PR。
模板和UITornado 包含一個簡單,快速并靈活的模板語言. 本節(jié)介紹了語言以及相關(guān)的問題,比如國際化.
Tornado 也可以使用其他的Python模板語言, 雖然沒有準備把這些系統(tǒng)整合到 RequestHandler.render 里面. 而是簡單的將模板轉(zhuǎn)成字符串并傳遞給 RequestHandler.write
配置模板默認情況下, Tornado會在和當前.py文件相同的目錄查找關(guān)聯(lián)的模板文件. 如果想把你的模板文件放在不同的目錄中, 可以使用template_pathApplication setting (或復(fù)寫 RequestHandler.get_template_path 如果你不同的處理函數(shù)有不同的模板路徑).
為了從非文件系統(tǒng)位置加載模板, 實例化子類 tornado.template.BaseLoader并為其在應(yīng)用設(shè)置(application setting)中配置template_loader.
默認情況下編譯出來的模板會被緩存; 為了關(guān)掉這個緩存也為了使(對目標的)修改在重新加載后總是可見, 使用應(yīng)用設(shè)置(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 %}來標識結(jié)束. 我們也支持 模板繼承(template inheritance) 使用extends和block標簽聲明, 這些內(nèi)容的詳細信息都可以在 tornado.template 中看到.
表達式可以是任意的Python表達式, 包括函數(shù)調(diào)用. 模板代碼會在包含以下對象和函數(shù)的命名空間中執(zhí)行 (注意這個列表適用于使用 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`設(shè)置的條目
任何傳遞給 RequestHandler.render 或RequestHandler.render_string 的關(guān)鍵字參數(shù)
當你正在構(gòu)建一個真正的應(yīng)用, 你可能想要使用Tornado模板的所有特性,尤其是目標繼承. 閱讀所有關(guān)于這些特性的介紹在 tornado.template部分 (一些特性, 包括UIModules是在 tornado.web 模塊中實現(xiàn)的)
在引擎下, Tornado模板被直接轉(zhuǎn)換為Python. 包含在你模板中的表達式會逐字的復(fù)制到一個代表你模板的Python函數(shù)中. 我們不會試圖阻止模板語言中的任何東西; 我們明確的創(chuàng)造一個高度靈活的模板系統(tǒng), 而不是有嚴格限制的模板系統(tǒng). 因此, 如果你在模板表達式中隨意填充(代碼), 當你執(zhí)行它的時候你也會得到各種隨機錯誤.
所有模板輸出默認都會使用 tornado.escape.xhtml_escape 函數(shù)轉(zhuǎn)義.這個行為可以通過傳遞autoescape=None給 Application 或者tornado.template.Loader 構(gòu)造器來全局改變, 對于一個模板文件可以使用{% autoescape None %}指令, 對于一個單一表達式可以使用{% raw ...%}來代替{{ ... }}. 此外, 在每個地方一個可選的轉(zhuǎn)義函數(shù)名可以被用來代替None.
注意, 雖然Tornado的自動轉(zhuǎn)義在預(yù)防XSS漏洞上是有幫助的, 但是它并不能勝任所有的情況. 在某一位置出現(xiàn)的表達式, 例如Javascript 或 CSS, 可能需要另外的轉(zhuǎn)義. 此外, 要么是必須注意總是在可能包含不可信內(nèi)容的HTML中使用雙引號和 xhtml_escape , 要么必須在屬性中使用多帶帶的轉(zhuǎn)義函數(shù)(參見 e.g. http://wonko.com/post/html-escaping)
國際化當前用戶的區(qū)域設(shè)置(無論他們是否登錄)總是可以通過在請求處理程序中使用self.locale或者在模板中使用locale進行訪問. 區(qū)域的名字(e.g.,en_US) 可以通過locale.name獲得, 你可以翻譯字符串通過 Locale.translate 方法. 模板也有一個叫做_()全局函數(shù)用來進行字符串翻譯. 翻譯函數(shù)有兩種形式:
_("Translate this string")
是直接根據(jù)當前的區(qū)域設(shè)置進行翻譯, 還有:
_("A person liked this", "%(num)d people liked this", len(people)) % {"num": len(people)}
是可以根據(jù)第三個參數(shù)的值來翻譯字符串單復(fù)數(shù)的. 在上面的例子中,如果len(people)是1, 那么第一句翻譯將被返回, 其他情況第二句的翻譯將會返回.
翻譯最通用的模式四使用Python命名占位符變量(上面例子中的%(num)d) 因為占位符可以在翻譯時變化.
這是一個正確的國際化模板:
FriendFeed - {{ _("Sign in") }}
默認情況下, 我們通過用戶的瀏覽器發(fā)送的Accept-Language頭來發(fā)現(xiàn)用戶的區(qū)域設(shè)置. 如果我們沒有發(fā)現(xiàn)恰當?shù)?b>Accept-Language值, 我們會使用en_US. 如果你讓用戶進行自己偏愛的區(qū)域設(shè)置, 你可以通過復(fù)寫 RequestHandler.get_user_locale 來覆蓋默認選擇的區(qū)域:
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,那我們(繼續(xù))依靠Accept-Language頭(進行判斷).
tornado.locale 模塊支持兩種形式加載翻譯: 一種是用gettext和相關(guān)的工具的.mo格式, 還有一種是簡單的.csv格式.應(yīng)用程序在啟動時通常會調(diào)用一次 tornado.locale.load_translations或者 tornado.locale.load_gettext_translations 其中之一; 查看這些方法來獲取更多有關(guān)支持格式的詳細信息..
你可以使用 tornado.locale.get_supported_locales() 得到你的應(yīng)用所支持的區(qū)域(設(shè)置)列表. 用戶的區(qū)域是從被支持的區(qū)域中選擇距離最近的匹配得到的.例如, 如果用戶的區(qū)域是es_GT, 同時es區(qū)域是被支持的, 請求中的self.locale將會設(shè)置為es. 如果找不到距離最近的匹配項, 我們將會使用en_US.
UI 模塊Tornado支持UI modules使它易于支持標準, 在你的應(yīng)用程序中復(fù)用UI組件. UI模塊像是特殊的函數(shù)調(diào)用來渲染你的頁面上的組件并且它們可以包裝自己的CSS和JavaScript.
例如, 如果你實現(xiàn)一個博客, 并且你想要有博客入口出現(xiàn)在首頁和每篇博客頁, 你可以實現(xiàn)一個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)
在你的應(yīng)用設(shè)置中, 使用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 %}語法調(diào)用一個模塊. 例如,你可以調(diào)用Entry模塊從home.html:
{% for entry in entries %} {% module Entry(entry) %} {% end %}
和entry.html:
{% module Entry(entry, show_comments=True) %}
模塊可以包含自定義的CSS和JavaScript函數(shù), 通過復(fù)寫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函數(shù)只能在模板中通過{% module Template(...) %}才可用. 不像{% include ... %}指令, 模板模塊有一個明確的命名空間它們的包含模板-它們只能看到全局模板命名空間和它們自己的關(guān)鍵字參數(shù).
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/37722.html
摘要:譯者說于年月日發(fā)布,該版本正式支持的關(guān)鍵字,并且用舊版本編譯同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次,這是最后一個支持和的版本了,在后續(xù)的版本了會移除對它們的兼容。本節(jié)最好直接在或者閱讀,以獲得更好的閱讀體驗格式支持。 譯者說 Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5的async/await關(guān)鍵字,并且用舊版本CPython編譯Torn...
閱讀 1575·2021-11-24 09:39
閱讀 1064·2021-11-22 15:11
閱讀 2220·2021-11-19 11:35
閱讀 1643·2021-09-13 10:37
閱讀 2482·2021-09-03 10:47
閱讀 2166·2021-08-30 09:47
閱讀 1644·2021-08-20 09:39
閱讀 2924·2019-08-30 14:13