可以覆盖sub-def所以mako就像继承的python类一样工作吗?

时间:2015-08-26 05:06:13

标签: python templates mako

我试图创建一些可重复使用的小部件'在mako中,使用defs。我想在1个地方定义所有defs,所以我可以导入1个文件并根据需要调用每个小部件。

如果我的mako模板是python对象,我会有点像;

class Div(object):
    element = 'div'
    def render(self):
        return '<{0}>Hello</{0}>'.format(self.element)

class Span(Div):
    element = 'span'

以下是我在mako中尝试过的内容,但它不起作用;

<%def name="div()">
    <%def name="element()">div</%def>
    <${element()}>Hello</${element()}
</%def>

<%def name="span()">
    <%def name="element()">span</%def>
    <${div()}>
</%def>

如果我调用span(),则渲染与div()相同。我相信这是因为元素sub-def没有被覆盖,因为没有任何继承在起作用。我也尝试过像${self.element()}这样的事情。

阅读mako文档,我不确定是否可以这样做。

  

上面的标题()def,因为它是def中的def,不是模板导出的命名空间的一部分,也不会成为self的一部分。如果继承的模板确实在顶层定义了自己的标题def,那么它将被调用,但无论如何,上面的“默认标题”根本不存在。

如果这是一个普通的模板,块标签和继承可以正常工作,但我注意到以下几点;

  

所以当&lt;%block&gt;标签解除了外部不可用的嵌套块的限制,为了实现这一点,它增加了限制,即单个模板中的所有块名称在模板中需要全局唯一,并且另外一个&lt;%block&gt;无法在&lt;%def&gt;内定义。这是一个更受限制的标签,适用于比&lt;%def&gt;更具体的用例。

所以我不认为我可以用任何其他方式使用块来完成这项任务。

也许有不同的方式,或者不同的模板系统可以更好地处理这个问题?

2 个答案:

答案 0 :(得分:1)

如果您将html标记作为参数传递,则无需从div继承span。

    <%def name="tag(tag='div', word='Hello')">
      <${tag}>
        ${word}
      </${tag}>
    </%def>

答案 1 :(得分:0)

对于小部件库,您应该使用def calls with embedded content。我不明白你是如何进入那些“getattr”的东西,你可以像记录的那样使用这些标签:

from mako import lookup

l = lookup.TemplateLookup()

l.put_string(
    "functions",
    """

<%def name="widget(tag='div')">\
    <${tag}>\
        ${caller.body()}\
    </${tag}>\
</%def>

<%def name="div()">\
    <%self:widget tag='div'>\
        ${caller.body()}\
    </%self:widget>\
</%def>

<%def name="span()">\
    <%self:widget tag='span'>\
        ${caller.body()}\
    </%self:widget>\
</%def>

""")

l.put_string(
    "caller",
    """
<%namespace name="functions" file="functions"/>

<%functions:span>
    im a span
</%functions:span>

<%functions:div>
    im a div
</%functions:div>


<%functions:widget tag='foob'>
    im a foob
</%functions:widget>

""")


print l.get_template("caller").render()

输出:

    <span>                
im a span
    </span>

    <div>                
im a div
    </div>


<foob>        
im a foob
</foob>