Один вид (главная страница) для многих контроллеров (подвиды) - PullRequest
1 голос
/ 22 февраля 2009

Примечания: Невозможно использовать Javascript или iframes. На самом деле я не могу доверять клиентскому браузеру делать что-либо, кроме крайних основ.

Я перестраиваю старое приложение PHP4 как приложение MVC, и большая часть моих исследований в настоящее время сосредоточена на фреймворке Pylon.

Одна из первых странных проблем, с которыми я столкнулся, и одна, которую я решал в прошлом, используя iframes или, что еще лучше, javascript отображает динамическую коллекцию «виджетов», которые похожи на дайджест-представления типичного представления индекса контроллера .

Лучший способ визуализировать мою проблему - это посмотреть на персональную главную страницу Google. Они решают проблему с Javascript, но для моего сценария javascript и почти все, что выше базового XHTML, невозможно.

Одна идея, над которой я начал работать, состояла в том, чтобы мой контроллер Frontpage опрашивал базу данных или другую службу для текущих активированных виджетов, а затем брал список кортежей / диктов, динамически создавал экземпляры каждого контроллера и формировал список / диктат визуализации. просматривают и передают это представлению главной страницы и позволяют ему разобраться.

То есть с кодом peusudo:

Get request goes to WSGI
WSGI calls pylons
Pylons routes to Frontpage.index()
Frontpage.index() 
   myViews = list()
   for WidgetController in ActiveWidegets():
        myViews.append(subRender(WidgetController, widgetView))

c.subviews = myViews
render(frontpage.mako)

Странные биты о subRender

  • Динамический импорт контроллеров через __import__ (в настоящее время жестко задан в пространство имен проекта :()
  • Потенциал может быть очень дорогим (большинство вызовов виджетов можно кэшировать, но одна из них - панель пользователя)

Я чувствую, что должен быть лучший способ или, возможно, механизм, уже реализованный в WSGI, или еще лучше Pylons, чтобы сделать это, но на данный момент наиболее близким является этот служебный метод: http://www.pylonshq.com/docs/en/0.9.7/modules/controllers_util/#pylons.controllers.util.forward, но кажется немного сумасшедшим строить N экземпляров пилонов поверх пилонов только для того, чтобы получить коллекцию видов.

Ответы [ 2 ]

6 голосов
/ 24 апреля 2009

Хотя в большинстве случаев я бы рекомендовал то, что вы изначально заявили, используя Javascript для загрузки каждого виджета, так как это не вариант, я думаю, вам нужно будет сделать что-то немного другое.

Помимо использования подхода, состоящего в попытке заставить один фронт-контроллер пройти через все необходимые виджеты и построить их, альтернативой, которую вы, возможно, захотите рассмотреть, является более мощное использование шаблонов в Mako.

На самом деле вы можете определить небольшие блоки как Mako def, которые, конечно, имеют полную мощность Python. Чтобы избежать загрязнения шаблонов Mako доменной логикой, не забудьте сохранить все это в своих моделях и просто вызывать экземпляры модели в определениях Mako по мере необходимости, чтобы этот компонент страницы создавался сам.

Огромным преимуществом этого подхода является то, что, поскольку Mako def поддерживает аргументы кеша, вы фактически можете сделать так, чтобы компоненты страницы сами решали, как кешировать себя. Возможно, боковая панель должна быть кэширована в течение 5 минут, но верхняя панель, например, меняет каждый удар. Кроме того, поскольку компонент запускает попадание в базу данных, вы сохраняете попадания в базу данных, когда компонент кэшируется сам.

ToscaWidgets не обладает такой производительностью, чтобы сделать его очень выполнимым вариантом в более широком масштабе, поэтому я бы держался подальше от этого.

Что касается некоторых изменений в вашей существующей идее, убедитесь, что вы на самом деле не используете контроллеры Pylons для «виджетов», так как они делают гораздо больше для поддержки WSGI, который вам не нужен для создания страницы виджетов.

Я бы подумал, чтобы все классы Widget работали так:

class Widget(object):
    def process(self):
        # Determine if this widget should process a POST aimed at it
        # ie, one of the POST args is a widget id indicating the widget
        # to handle the POST

    def prepare(self):
        # Load data from the database if needed in prep for the render

    def render(self):
        # return the rendered content

    def __call__(self):
        self.process()
        self.prepare()
        return self.render()

Тогда просто сделайте так, чтобы ваш основной шаблон Mako перебирал экземпляры виджетов, и вызывайте их для их вывода.

0 голосов
/ 16 марта 2009

Вы можете использовать ToscaWidgets для инкапсуляции ваших виджетов вместе с сохраненным списком включенных виджетов для каждого пользователя (в базе данных или другой службе, как вы предлагаете). Передайте список включенных виджетов ToscaWidget в представление, и виджеты будут отображаться самостоятельно (включая динамическое добавление ссылок CSS / JavaScript на страницу, если виджет требует этих ресурсов).

...