Как добавить переменные в dict, используемый для шаблона декоратором в TurboGears2? - PullRequest
0 голосов
/ 02 февраля 2012

Когда метод предоставлен, он может вернуть dict, используемый шаблоном:

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

Я могу иметь доступ к украшению, но не к экспонируемому объекту и не к контроллеру

Как я могу это сделать?Заранее благодарим за помощь

Лоран

Ответы [ 2 ]

1 голос
/ 15 марта 2012

Вы всегда можете получить доступ к объекту и методу контроллера, которые обрабатывают текущий запрос, используя tg.request.controller_state.controller и tg.request.controller_state.method

Это должно позволить получить доступ к переменным контроллера из декоратора @before_render.

Имейте в виду, что установка переменных внутри объекта контроллера не предлагается, так как он используется несколькими потоками. Рекомендуемый способ - использовать tg.tmpl_context для хранения временных переменных, специфичных для запроса.

Вам также может быть интересно взглянуть на tgext.menu для создания меню приложений

0 голосов
/ 03 марта 2012

Вот мой пример понимания декоратора 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».Мы изменили и обновили его консистенцию, а затем отправили как новые данные.

...