在子模板或控制器范围的变量中声明的访问变量

时间:2011-04-05 08:18:44

标签: python inheritance pylons pyramid mako

我有一个小的mako模板层次结构,类似于:

base.mako

<h1>${self.view()}</h1>
${listactions(self.mainactions)}
${self.body()}

<%def name="listactions(actions)">
    <ul>
    % for action in actions:
        <li>${action}</li>
    % endfor
    </ul>
</%def>

clientsbase.mako

<%inherit file="base.mako"/>
<%def name="view()">Clients</%def>
<%
    mainactions = [request.route_url('clientsnew')]
%>

clientsindex.mako

<%inherit file="clientsbase.mako"/>
This is the index

问题是当我尝试访问客户端索引视图时呈现clientsindex.mako我收到错误 AttributeError:命名空间'self:/base.mako'没有成员'mainactions'。< / p>

这样做的正确方法是什么?我已经浏览了mako文档,到目前为止我发现的是我可以使用模块级python块来声明mainactions,然后在base.mako中执行 self.attr.mainactions 。问题在于此块我无法访问请求对象。

我想另一个问题是:在我的情况下,我使用函数作为view-callables,但是假设我已经编写了一个单独的clients.py视图文件,其中包含与客户端相关的所有视图。有没有办法从clients.py文件中以某种方式设置类似控制器范围的上下文变量?这样我就可以在模板的上下文中设置一个mainactions变量,而不必在每个视图的dict中返回它。

4 个答案:

答案 0 :(得分:1)

这是一个相当古老的问题,但在这里,我想它可能会成功。请记住,在编写模板时,您实际上默认显示函数body()

我的猜测是mainactions被定义为self.body()的局部变量。但是一切都很酷,因为我们可以获得自我......

所以不要写:

mainactions = [request.route_url('clientsnew')]

你应该尝试写作:

self.mainactions = [request.route_url('clientsnew')]

那就是说,这并不是实现你想做的事情的好方法。如果我是你,我会使用defblock来完成。

base.mako

<h1>${self.view()}</h1>
<%block name="mainaction">
</%block>
${self.body()}

<%def name="listactions(actions)">
    <ul>
    % for action in actions:
        <li>${action}</li>
    % endfor
    </ul>
</%def>

clientbase.mako

<%inherit file="base.mako"/>
<%def name="view()">Clients</%def>
<%block name="mainaction"
    ${request.route_url('clientsnew')}
</%block>

其余内容不会改变... def的内容是你只是在父母的def上,然后在base.mako中使用你想要的def

这就是它。

答案 1 :(得分:0)

嗯......我已经多年没有在挂架上写任何东西,也没有安装任何挂架进行检查。但请尝试编写next.mainactions而不是self.mainactions,看看会发生什么。

答案 2 :(得分:0)

这个答案很老,所以我不知道你是否已经解决了这个问题。

可能有效的一种方法是在view()def中移动你的python块。这样,变量实际上将在base.mako中调用。

在我自己的应用程序中,我创建了一个view对象,其中包含我在整个应用程序中需要的一组上下文变量,例如view.page,view.perpage等。在每个可调用的视图上,我启动这个view(自动计算来自gets,post_data,routes等的上下文变量)并将其作为上下文变量传递。因此,您始终可以传递view.mainactions,并且只要您将其保留为None,就不会遇到应用程序中的任何KeyErrors。

答案 3 :(得分:0)

这个答案是针对你的“其他问题”:)

您可以将视图定义为Controller类上的方法。这样,您可以将Controller-wide变量输出分解为常用方法:

from pyramid.view import view_config
from myproject.resources import MyResource


class MyController(object):

    def __init__(self, request):
        self.request = request

    def respond(self, additionalVars):
        additionalVars['myCommonVar1'] = 'common value'
        return additionalVars

    @view_config(
        context='myproject.resources:MyResource',
        request_method='GET',
        renderer='one.mak')
    def get_one(self):
        return self.respond({'var2':'sth'})

    @view_config(
        context='myproject.resources:MyResource',
        name = 'two',
        request_method='GET',
        renderer='two.mak')
    def get_two(self):
        return self.respond({'var3':'sth else'})