CMSimple Drupal Yii 內容管理系統三方案 - 提升台灣中小企業競爭力

目前位置:   首頁 > Welcome to CMSimple > CherryPy and Mako > Mako Manual

Mako Manual

Mako 是一套以 Python 編寫的樣版引擎.

Mako 樣版可從各式內容資料轉換而來, 這些內容包括 XML, HTML 或者是電子郵件內容. Mako 樣版檔案可以內置特定的指令來代表變數值或表示式取代, 控制結構(包含條件式或重複迴圈), 伺服端註解, Python 程式段, 或者是具有特殊意義的標註.

上面所提到的 Mako 檔案內容在執行時會轉換成 Python 程式碼, 換言之, 使用 Mako 樣版可以充分展現 Python 的所有功能.


最簡單的表示式取代為變數取代. 語法為 ${}, 取法於 Perl 程式語言, Genshi, JSP 等程式架構.

this is x: ${x}

x 為呼叫 Mako 樣版函式的 Python 程式碼中的對應變數或者是直接在樣版檔案中所指定的變數值, 假如無法在上述兩個地方找到 x 的對應值, x 將會以 UNDEFINED 替代.

${} 中除了可以是單一 Python 變數外, 也可以是較長的表示式:

pythagorean theorem: ${pow(x,2) + pow(y,2)}


Mako 內建多個跳脫機制, 其中包含 HTML, URI 與 XML 跳脫, 也可以使用過濾或刪減函式. 這些跳脫式可以使用 | 運算子與表示式替代方法結合使用.

${"this is some text" | u}

u 代表 URL 跳脫, h 代表 HTML 跳脫, x 則代表 XML 跳脫, trim 則是 trim 函式.

除了內建的跳脫函式, 使用者也可以自行建立所需的跳脫函式.


 Mako 的控制架構包含: 條件式, 重複迴圈, 也可以是 try/except.

控制結構以 % 開頭, 隨後接 Python 程式語法, 但是必須利用 %end<name> 來結束.

% if x==5:

this is some output
% endif

上述程式碼中的 % 之前不可以有其他文字, 但卻不一定要在第一個字元, 而且控制結構是否內縮可由使用者決定.

% for a in ['one', 'two', 'three', 'four', 'five']:

% if a[0] == 't':
its two or three
% elif a[0] == 'f':
% else:
% endif
% endfor

至於要在內容中列印 %, 可以使用 %%.

%% some text

%% some more text



% for a in ("one", "two", "three"):
<li>Item ${loop.index}: ${a}</li>
% endfor


單行註解使用 ##

## this is a comment.

多行註解則使用 <%doc>內文</%doc>


these are comments
more comments


在每一行的最後放入 \ 符號, 表示要蓋掉該行的跳行指令, 以便將內容延續到下一行.

here is a line that goes onto \

another line.


here is a line that goes onto another line.

Python 程式段

Python 程式段可以放入 <% %> 標註中:

this is a template

x = db.get_resource('foo')
y = [z.element for z in x if x.frobnizzle==5]

% for elem in y:
element: ${elem}
% endfor

Within <% %>, you’re writing a regular block of Python code. While the code can appear with an arbitrary level of preceding whitespace, it has to be consistently formatted with itself. Mako’s compiler will adjust the block of Python to be consistent with the surrounding generated Python code.

Module-level Blocks
A variant on <% %> is the module-level code block, denoted by <%! %>. Code within these tags is executed at the module level of the template, and not within the rendering function of the template. Therefore, this code does not have access to the template’s context and is only executed when the template is loaded into memory (which can be only once per application, or more, depending on the runtime environment). Use the <%! %> tags to declare your template’s imports, as well as any pure-Python functions you might want to declare:

import mylib
import re

def filter(text):
return re.sub(r'^@', '', text)
Any number of <%! %> blocks can be declared anywhere in a template; they will be rendered in the resulting module in a single contiguous block above all render callables, in the order in which they appear in the source template.

The rest of what Mako offers takes place in the form of tags. All tags use the same syntax, which is similar to an XML tag except that the first character of the tag name is a % character. The tag is closed either by a contained slash character, or an explicit closing tag:

<%include file="foo.txt"/>

<%def name="foo" buffered="True">
this is a def
All tags have a set of attributes which are defined for each tag. Some of these attributes are required. Also, many attributes support evaluation, meaning you can embed an expression (using ${}) inside the attribute text:

<%include file="/foo/bar/${myfile}.txt"/>
Whether or not an attribute accepts runtime evaluation depends on the type of tag and how that tag is compiled into the template. The best way to find out if you can stick an expression in is to try it! The lexer will tell you if it’s not valid.

Heres a quick summary of all the tags:


This tag defines general characteristics of the template, including caching arguments, and optional lists of arguments which the template expects when invoked.

<%page args="x, y, z='default'"/>
Or a page tag that defines caching characteristics:

<%page cached="True" cache_type="memory"/>
Currently, only one <%page> tag gets used per template, the rest get ignored. While this will be improved in a future release, for now make sure you have only one <%page> tag defined in your template, else you may not get the results you want. The details of what <%page> is used for are described further in The body() Method as well as Caching.


A tag that is familiar from other template languages, %include is a regular joe that just accepts a file argument and calls in the rendered result of that file:

<%include file="header.html"/>

hello world

<%include file="footer.html"/>
Include also accepts arguments which are available as <%page> arguments in the receiving template:

<%include file="toolbar.html" args="current_section='members', username='ed'"/>

The %def tag defines a Python function which contains a set of content, that can be called at some other point in the template. The basic idea is simple:

<%def name="myfunc(x)">
this is myfunc, x is ${x}

The %def tag is a lot more powerful than a plain Python def, as the Mako compiler provides many extra services with %def that you wouldn’t normally have, such as the ability to export defs as template “methods”, automatic propagation of the current Context, buffering/filtering/caching flags, and def calls with content, which enable packages of defs to be sent as arguments to other def calls (not as hard as it sounds). Get the full deal on what %def can do in Defs and Blocks.


%block is a tag that is close to a %def, except executes itself immediately in its base-most scope, and can also be anonymous (i.e. with no name):

<%block filter="h">
some <html> stuff.
Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way to do inheritance:

<%block name="header">
<h2><%block name="title"/></h2>
Blocks are introduced in Using Blocks and further described in Inheritance.

New in version 0.4.1.


%namespace is Mako’s equivalent of Python’s import statement. It allows access to all the rendering functions and metadata of other template files, plain Python modules, as well as locally defined “packages” of functions.

<%namespace file="functions.html" import="*"/>
The underlying object generated by %namespace, an instance of mako.runtime.Namespace, is a central construct used in templates to reference template-specific information such as the current URI, inheritance structures, and other things that are not as hard as they sound right here. Namespaces are described in Namespaces.


Inherit allows templates to arrange themselves in inheritance chains. This is a concept familiar in many other template languages.

<%inherit file="base.html"/>
When using the %inherit tag, control is passed to the topmost inherited template first, which then decides how to handle calling areas of content from its inheriting templates. Mako offers a lot of flexibility in this area, including dynamic inheritance, content wrapping, and polymorphic method calls. Check it out in Inheritance.


Any user-defined “tag” can be created against a namespace by using a tag with a name of the form <%<namespacename>:<defname>>. The closed and open formats of such a tag are equivalent to an inline expression and the <%call> tag, respectively.

<%mynamespace:somedef param="some value">
this is the body
To create custom tags which accept a body, see Calling a Def with Embedded Content and/or Other Defs.

New in version 0.2.3.


The call tag is the “classic” form of a user-defined tag, and is roughly equivalent to the <%namespacename:defname> syntax described above. This tag is also described in Calling a Def with Embedded Content and/or Other Defs.


The %doc tag handles multiline comments:

these are comments
more comments
Also the ## symbol as the first non-space characters on a line can be used for single line comments.


This tag suspends the Mako lexer’s normal parsing of Mako template directives, and returns its entire body contents as plain text. It is used pretty much to write documentation about Mako:

<%text filter="h">
heres some fake mako ${syntax}
<%def name="x()">${x}</%def>
Returning Early from a Template
Sometimes you want to stop processing a template or <%def> method in the middle and just use the text you’ve accumulated so far. You can use a return statement inside a Python block to do that.

% if not len(records):
No records found.
<% return %>
% endif
Or perhaps:

if not len(records):


Powered by CMSimple_XH| Template:| 登入