【问题标题】:How to inject vars into the dict used for template by a decorator in TurboGears2?如何将变量注入到 TurboGears2 中装饰器用于模板的字典中?
【发布时间】:2012-02-02 07:20:59
【问题描述】:

当一个方法被暴露时,它可以返回一个模板使用的字典:

class RootController(TGController):
    @expose('myapp.templates.index')
    def index(self):
        self.mykey = "foo"
        self.mymenu = ["item1", "item2", "item3"]
        self.selected = "item1"
        return dict( mykey=self.mykey, mymenu=self.mymenu, selected=self.selected)

此代码运行良好。现在我想将菜单样板封装成这样的装饰器:

class RootController(TGController):
    @expose('myapp.templates.index')
    @menu()
    def index(self):
        self.mykey = "foo"
        self.mymenu = ["item1", "item2", "item3"]
        self.selected = "item1"
        return dict( mykey=self.mykey)

但我不知道如何编写这个菜单装饰器。如果我使用:

def before_render_cb(remainder, params, output):
    return output.update( dict(mymenu=["item1", "item2", "item3"], selected="item1")) 
    
class RootController(TGController):
    @expose('myapp.templates.index')
    @before_render(before_render_cb)
    def index(self):
        self.mykey = "foo"
        self.mymenu = ["item1", "item2", "item3"]
        self.selected = "item1"
        return dict( mykey=self.mykey)

它将添加 mymenu 并选择到 dict 但我无权访问控制器的实例属性(self.mymenu 和 self.selected)

如果我使用装饰器:

class menus(object):
    def __call__(self, func):
        deco = Decoration.get_decoration(func)
        return func

我可以访问装饰,但不能访问控制器,也不能访问对象。

我该怎么做?

【问题讨论】:

    标签: menu controller decorator turbogears2


    【解决方案1】:

    您始终可以使用tg.request.controller_state.controllertg.request.controller_state.method 访问处理当前请求的控制器对象和方法

    这应该可以从 @before_render 装饰器访问控制器变量。

    请记住,不建议在控制器对象内设置变量,因为它在多个线程之间共享。建议的方法是使用tg.tmpl_context 来存储特定于请求的临时变量。

    您可能也有兴趣查看tgext.menu 以生成应用程序菜单

    【讨论】:

      【解决方案2】:

      这是我理解“before_render”装饰器的示例:

      #---=== read this section second: ===---
      
      def make_menu_from_controller(remainder, params, output):
          controller = output.pop('controller') #Here we remove RootController sent by "index" and write it to "controller" variable.
                                                #Only {'page':'index'} left inside "output" variable
          return output.update(dict(mykey=controller.mykey, mymenu=controller.mymenu, selected=controller.selected)) #here we update dict adding "mykey", "mymenu" and "selected" keys. 
      
      #---=== read this section first: ===---
      
      class RootController(TGController):
      
          def __init__(self): #here we initiate variables, which are not changed during surfing
              self.mykey = "foo"
              self.mymenu = ["item1", "item2", "item3"]
      
          @expose('myapp.templates.index')
          @before_render(make_menu_from_controller)
          def index(self):
              self.selected = "item1"
              return dict(page='index', controller=self) #RootController sends itself
      

      如您所见,“before_render”装饰器拦截发送的数据,对其进行处理并返回另一个数据。 “output”是“before_render”的局部变量。我们更改并更新了它的一致性,然后将其作为新数据发送。

      【讨论】:

        猜你喜欢
        • 2013-07-25
        • 2013-03-29
        • 1970-01-01
        • 2021-02-27
        • 2019-03-26
        • 2019-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多