В чем разница между шаблоном в ZCML и ViewPageTemplateFile
При создании BrowserView в Plone я знаю, что я могу при желании настроить шаблон с ZCML следующим образом:
<configure
xmlns:browser="http://namespaces.zope.org/browser"
>
<browser:page
…
class=".foo.FooView"
template="foo.pt"
…
/>
</configure>
Или альтернативно в коде:
# foo.py
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.publisher.browser import BrowserPage
class FooView(BrowserPage):
"""
My View
"""
def __call__(self):
return ViewPageTemplateFile('foo.pt')(self)
Есть ли разница между этими двумя подходами? Оба они дают одинаковый результат.
Подвопрос: я знаю, что есть BrowserView
Первый класс можно импортировать, но обычно каждый использует BrowserPage
, Что, если между этими двумя классами существуют существенные различия?
3 ответа
Примечание: чтобы быть полностью эквивалентным ZCML, вы должны установить index
переменная, чтобы указать, какой шаблон вы используете. Таким образом, настройка TTW тоже будет работать.
# foo.py
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.publisher.browser import BrowserPage
class FooView(BrowserPage):
index = ViewPageTemplateFile('foo.pt')
Еще один шаблон, который вы можете использовать в представлении браузера, - это добавление метода обновления.
class FooView(BrowserPage):
index = ViewPageTemplateFile('foo.pt')
def __call__(self):
self.update()
return self.index()
def update(self):
self.portal_catalog = ... # initialize code
Но это не вопрос.
Так в чем же разница? Там нет разницы. Вид браузера должен быть вызываемым. Директива ZCML создает этот вызываемый способ так, что объект имеет индекс, который должен возвращать отображаемую страницу.
Но создание шаблона для каждого вызова (ваш пример) имеет одно отличие: вы создаете новый экземпляр шаблона при каждом вызове представления браузера. Это не так с переменной класса.
Последний вариант: вам не нужен аргумент класса в директиве
<configure xmlns:browser="http://namespaces.zope.org/browser">
<browser:page
…
template="foo.pt"
…
/>
</configure>
Для получения дополнительной информации вы должны прочитать код директивы, которая использует SimpleViewClass, где src - имя шаблона.
В Plone вы можете настроить шаблон TTW (через portal_view_customizations
) только когда шаблон зарегистрирован явно (например, с использованием директив ZCML или Grok).
Если вы определяете шаблон только в вашем __call__
вы не увидите это в portal_view_customizations
,
Кроме того, я предполагаю, что загрузка шаблона в методе перезагрузит его с диска для каждого экземпляра представления (каждого запроса).
AFAIK, нет никакой разницы. Директива ZCML генерирует ViewClass с ViewPageTemplateFile
и отображает шаблон на __call__
, Увидеть zope.browserpage.metaconfigure.page
линии 132, 151.
То же самое вы делаете в своем примере: вы явно создаете экземпляр шаблона в своем __call__
метод.
Что касается подвопроса: насколько я понимаю, существенные различия не очевидны в контексте Zope2/Plone. На основе интерфейса (zope.publisher.interfaces.browser.IBrowserPage
), BrowserPage - это базовый класс, от которого вы хотите наследовать, поскольку он реализует __call__
а также browserDefault
, Тем не менее, это не имеет значения, если вы используете BrowserPage
или же BrowserView
с Plone.