Friday, December 20, 2013

mako二三事 -- Blocks二

二、命名Block

1. 命令Block的使用

相对匿名block,命名block的用途更广泛,不过命名block也有一些特有的属性,我们先来看看一段常用的代码:

<html>
<%block name="header">
    <head>
        <title>
            <%block name="title">Title</%block>
        </title>
    </head>
</%block>
<body>
</body>
</html>

这段代码中定义两个block,其中title内嵌在header中。不过在mako中,尽管他们的定义是有内嵌关系的,生成的block也是全局的。也就是说只要是命名block,在模板里面都是可以全局引用的。上面模板生成的代码如下:

def render_body(context,**pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)
        def header():                   # 所有的block都是全局的,所以所有block都会在这里定义函数
            return render_header(context.locals_(__M_locals))
        def title():                        # 所有的block都是全局的,所以所有block都会在这里定义函数
            return render_title(context.locals_(__M_locals))
        __M_writer = context.writer()
        # SOURCE LINE 1
        __M_writer(u'\n\n')
        if 'parent' not in context._data or not hasattr(context._data['parent'], 'header'):
            context['self'].header(**pageargs)     # 如果有继承关系的话,提取最顶层的模板(self),然后调用其中的header block


        # SOURCE LINE 9
        __M_writer(u'\n\n\n
\n')        return ''
    finally:
        context.caller_stack._pop_frame()


def render_header(context,**pageargs):
    … ...


def render_title(context,**pageargs):
    … ...


2. 重复调用Block

一个block定义之后,可以在模板里面多次引用,引用方式跟函数调用一样。如:

<div name="page">
    <%block name="pagecontrol">
        <a href="">previous page
|        <a href="">next page
    </%block>

    <table>
        ## some content
    </table>

    ${pagecontrol()}
</div>

这段代码将在table上下都生成一个pagecontrol。

通过上面几个例子我们可以看到:
* Block定义是全局的,所以Block不能重名,即便是内嵌的Block也不能重名
* Block不像函数一样可以带参数
* Block 不能在def中、<% call>、<%namespacename:defname>等地方使用

No comments:

Post a Comment