在Python中使用Mako模版庫的簡單教程_python

來源:互聯網
上載者:User

Mako是一個高效能的Python模板庫,它的文法和API借鑒了很多其他的模板庫,如Django、Jinja2等等。
基本用法

建立模板並渲染它的最基本的方法是使用 Template 類:
 

from mako.template import Templatet = Template('hello world!')print t.render()

傳給 Template 的文本參數被編譯為一個Python模組。模組包含一個 render_body() 函數,它產生模板的輸出。調用 render() 方法時,Mako建立了一個模板的運行環境,並調用 render_body() 函數,把輸出儲存到緩衝,返回它的字串內容。
render_body() 函數中可以訪問一個變數集。可以向 render() 方法發送額外的關鍵詞參數來指定這些變數:
 

from mako.template import Templatet = Template('hello, ${name}!')print t.render(name='yeolar')

render() 方法使Mako建立一個 Context 對象,它儲存模板可以訪問的所有變數和一個用來儲存輸出的緩衝。也可以自己建立 Context ,用 render_context() 方法使模板用它來渲染:
 

from mako.template import Templatefrom mako.runtime import Contextfrom StringIO import StringIOt = Template('hello, ${name}!')buf = StringIO()c = Context(buf, name='yeolar')t.render_context(c)print buf.getValue()

使用檔案模板

Template 也可以從檔案載入模板,使用 filename 參數:
 

from mako.template import Templatet = Template(filename='/docs/tpl.txt')print t.render()

為了提高效能,從檔案載入的 Template 還可以在檔案系統中將產生的模組緩衝為一般的Python模組檔案(.py檔案),這通過添加 module_directory 參數實現:

from mako.template import Templatet = Template(filename='/docs/tpl.txt', module_directory='/tmp/mako_modules')print t.render()

上面的代碼渲染後,會建立一個/tmp/mako_modules/docs/tpl.txt.py檔案,其中包含模組的原始碼。下次同樣參數的 Template 建立時,自動重用這個模組檔案。
使用TemplateLookup

到現在的例子都是有關單個 Template 對象的用法。如果模板中的代碼要定位其他模板資源,需要某種使用URI來找到它們的方法。這種需求是由 TemplateLookup 類來達到的。這個類通過傳入一個模板尋找目錄的列表來構造,然後作為關鍵詞參數傳給 Template 對象:
 

from mako.template import Templatefrom mako.lookup import TemplateLookuplookup = TemplateLookup(directories=['/docs'])t = Template('<%include file="header.txt" /> hello word!', lookup=lookup)

上面建立的模板中包含檔案header.txt。為了尋找header.txt,傳了一個 TemplateLookup 對象給它。
通常,應用會以文字檔形式在檔案系統上儲存大部分或全部的模板。一個真正的應用會直接從 TemplateLookup 取得它的模板,使用 get_template() 方法,它接受需要的模板的URI作為參數:
 

from mako.template import Templatefrom mako.lookup import TemplateLookuplookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')def serve_template(t_name, **kwargs):  t = lookup.get_template(t_name)  print t.render(**kwargs)

上面的例子中我們建立了一個 TemplateLookup ,它從/docs目錄中尋找模板,並把所有的模組檔案儲存體到/tmp/mako_modules目錄中。通過將傳入的URI附加到每個尋找目錄來定位模板,如傳遞/etc/beans/info.txt,將尋找檔案/docs/etc/beans/info.txt,如果沒找到將拋出 TopLevelNotFound 異常。
當定位到模板的時候,傳給 get_template() 調用的URI也會作為 Template 的 uri 屬性。 Template 使用這個URI來得到模組檔案的名字,因此上面的例子中對/etc/beans/info.txt會建立模組檔案/tmp/mako_modules/etc/beans/info.txt.py。
設定收集的大小

TemplateLookup 還滿足將記憶體中緩衝的模板總數設為一個固定的值。預設情況 TemplateLookup 大小是不限的。可以用 collection_size 參數指定一個固定值:
 

lookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules', collection_size=500)

上面的 lookup 將模板載入到記憶體中的上限是500個。之後,它將使用LRU策略來清理替換模板。
設定檔案系統檢查

TemplateLookup 的另一個重要標誌是 filesystem_checks 。預設為 True ,每次 get_template() 方法返回一個模板,會比較原始模板檔案的修改時間和模板的最近載入時間,如果檔案更新,就重新載入和編譯模板。在生產系統中,將 filesystem_checks 設為 False 能獲得一些效能的提升。
使用Unicode和編碼

Template 和 TemplateLookup 可以設定 output_encoding 和 encoding_errors 參數來將輸出編碼為Python支援的編碼格式:
 

from mako.template import Templatefrom mako.lookup import TemplateLookuplookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')t = lookup.get_template('foo.txt')print t.render()

使用Python 3時,如果設定了 output_encoding , render() 方法將返回一個 bytes 對象,否則返回 string 。
render_unicode() 方法返回模板輸出為Python unicode 對象,Python 3為 string :
 

print t.render_unicode()

上面的方法沒有輸出編碼的參數,可以自行編碼:
 

print t.render_unicode().encode('utf-8', 'replace')

注意Mako中模板的底層輸出資料流是Python Unicode對象。
處理異常

模板異常可能發生在兩個地方。一個是當你尋找、解析和編譯模板的時候,一個是運行模板的時候。模板運行中發生的異常會正常在產生問題的Python代碼處拋出。Mako有自己的一組異常類,它們主要用於模板構造的尋找和編譯階段。Mako提供了一些庫常式用來對異常棧提供Mako的資訊,並將異常輸出為文本或HTML格式。Python檔案名稱、行號和程式碼片段會被轉換為Mako模板檔案名稱、行號和程式碼片段。Mako模板模組的行會被轉換為原始的模板檔案對應行。

text_error_template() 和 html_error_template() 函數用于格式化異常跟蹤。它們使用 sys.exc_info() 來得到最近拋出的異常。這些處理器的用法像下面這樣:
 

from mako import exceptionstry:  t = lookup.get_template(uri)  print t.render()except:  print exceptions.text_error_template().render()或者渲染為HTML:from mako import exceptionstry:  t = lookup.get_template(uri)  print t.render()except:  print exceptions.html_error_template().render()

html_error_template() 模板接受兩個選項:指定 full=False 只渲染HTML的一節,指定 css=False 關閉預設的樣式表。如:
 

print exceptions.html_error_template().render(full=False)

HTML渲染函數也可以用 format_exceptions 標誌加到 Template 中。這種情況下,模板在渲染階段的任何異常在輸出中的結果都會替換為 html_error_template() 的輸出:
 

t = Template(filename='/foo/bar', format_exceptions=True)print t.render()

注意上面模板的編譯階段發生在構造 Template 時,沒有定義輸出資料流。因此尋找、解析、編譯階段發生的異常正常情況下不會被處理,而是傳播下去。渲染前的追溯不包括Mako形式的行,這意味著渲染前和渲染中發生的異常會用不同的方式處理,因此 try/except 可能更常用。

錯誤模板函數使用的底層對象是 RichTraceback 對象。這個對象也可以直接用來提供自訂的錯誤視圖。下面是一個用法的範例:
 

from mako.exceptions import RichTracebacktry:  t = lookup.get_template(uri)  print t.render()except:  traceback = RichTraceback()  for (filename, lineno, function, line) in traceback.traceback:    print 'File %s, line %s, in %s' % (filename, lineno, function)    print line, '\n'  print '%s: %s' % (str(traceback.error.__class__.__name__), traceback.error)

整合Mako
在Django中整合Mako

通過Django的中介軟體可以整合Mako。首先需要安裝django-mako模組。
在Django項目的settings.py檔案中,修改 MIDDLEWARE_CLASSES ,添加 djangomako.middleware.MakoMiddleware 。使用 render_to_response() 函數即可使用:
 

from djangomako.shortcuts import render_to_responsedef hello_view(request):  return render_to_response('hello.txt', {'name': 'yeolar'})

在Tornado中整合Mako

在Tornado中可以直接使用Mako,下面是一個使用樣本:

import tornado.webimport mako.lookupimport mako.templateLOOK_UP = mako.lookup.TemplateLookup(    directories=[TEMPLATE_PATH], module_directory='/tmp/mako',    output_encoding='utf-8', encoding_errors='replace')class BaseHandler(tornado.web.RequestHandler):  def initialize(self, lookup=LOOK_UP):    '''Set template lookup object, Defalut is LOOK_UP'''    self._lookup = lookup  def render_string(self, filename, **kwargs):    '''Override render_string to use mako template.    Like tornado render_string method, this method    also pass request handler environment to template engine.    '''    try:      template = self._lookup.get_template(filename)      env_kwargs = dict(        handler = self,        request = self.request,        current_user = self.current_user,        locale = self.locale,        _ = self.locale.translate,        static_url = self.static_url,        xsrf_form_html = self.xsrf_form_html,        reverse_url = self.application.reverse_url,        )      env_kwargs.update(kwargs)      return template.render(**env_kwargs)    except:      # exception handler      pass  def render(self, filename, **kwargs):    self.finish(self.render_string(filename, **kwargs))
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.