【问题标题】:access variable declared in child template or controller-wide variables访问子模板中声明的变量或控制器范围的变量
【发布时间】:2011-07-29 18:37:19
【问题描述】:

我有一个小的 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: Namespace 'self:/base.mako' has no member 'mainactions'

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

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

【问题讨论】:

    标签: python inheritance pylons pyramid mako


    【解决方案1】:

    嗯...我已经很久没有在 pylons 中写过任何东西了,也没有安装任何 pylons 来检查它。但是请尝试写next.mainactions 而不是self.mainactions,看看会发生什么。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

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

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

        所以不要写:

        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

        差不多了。

        【讨论】:

          【解决方案4】:

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

          您可以将视图定义为 Controller 类的方法。这样,您可以将 Controller 范围的变量输出分解为通用方法:

          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'})
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-01-03
            • 1970-01-01
            • 1970-01-01
            • 2011-12-13
            • 2016-05-22
            • 2020-03-18
            • 2014-09-20
            相关资源
            最近更新 更多