ZCML和ViewPageTemplateFile中的模板有什么区别

acl*_*ark 6 python zope plone zcml

在Plone中创建BrowserView时,我知道我可以选择使用ZCML配置模板,如下所示:

<configure

    xmlns:browser="http://namespaces.zope.org/browser"
    >

    <browser:page
        …
        class=".foo.FooView"
        template="foo.pt"
        …
        />

</configure>
Run Code Online (Sandbox Code Playgroud)

或者在代码中:

# 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)
Run Code Online (Sandbox Code Playgroud)

这两种方法有什么区别吗?它们似乎都产生相同的结果.

子问题:我知道有一个BrowserView类可以导入,但通常每个人都使用BrowserPage.如果这两个类之间存在任何显着差异怎么办?

Ask*_*kka 7

在Plone中,portal_view_customizations只有在明确注册模板时(例如,使用ZCML或Grok指令),才能自定义模板TTW(via ).

如果仅在您的模板中定义模板__call__,则不会看到它portal_view_customizations.

另外,我猜测方法中的加载模板会为每个视图实例(每个请求)从磁盘重新加载它.


tou*_*tpt 7

注意:要完全等效于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')
Run Code Online (Sandbox Code Playgroud)

您可以在浏览器视图中使用的另一种模式是添加更新方法.

class FooView(BrowserPage):
    index = ViewPageTemplateFile('foo.pt')
    def __call__(self):
        self.update()
        return self.index()

    def update(self):
        self.portal_catalog = ...  # initialize code
Run Code Online (Sandbox Code Playgroud)

但这不是问题.


那么区别是什么呢?没有区别.浏览器视图必须是可调用的.ZCML指令以对象具有必须返回呈现页面的索引的方式构建此可调用对象.

但是在每次调用(您的示例)上创建模板都有一个区别:您在浏览器视图的每次调用时都在创建模板的新实例.类变量不是这种情况.

最后一个选项:您不需要指令中的类参数

<configure xmlns:browser="http://namespaces.zope.org/browser">
  <browser:page
    …
    template="foo.pt"
    …
    />
</configure>
Run Code Online (Sandbox Code Playgroud)

有关更多信息,您应该阅读该指令的代码,该代码使用SimpleViewClass,其中src是模板名称.