我试图创建一些可重复使用的小部件'在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;更具体的用例。
所以我不认为我可以用任何其他方式使用块来完成这项任务。
也许有不同的方式,或者不同的模板系统可以更好地处理这个问题?
答案 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>