简体   繁体   English

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

[英]What is the difference between template in ZCML and ViewPageTemplateFile

When creating a BrowserView in Plone, I know that I may optionally configure a template with ZCML like so: 在Plone中创建BrowserView时,我知道我可以选择使用ZCML配置模板,如下所示:

<configure

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

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

</configure>

Or alternatively in code: 或者在代码中:

# 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)

Is there any difference between the two approaches? 两种方法之间有什么区别吗? They both appear to yield the same result. 它们似乎都产生相同的结果。

Sub-question : I know there is a BrowserView class one can import, but conventionally everyone uses BrowserPage . 子问题 :我知道可以导入一个BrowserView类,但是通常每个人都使用BrowserPage What if any significant differences exist between the two classes? 如果两个类别之间存在显着差异怎么办?

In Plone, you can customize the template TTW (via portal_view_customizations ) only when the template is registered explicitly (eg using ZCML or Grok-directives). 在Plone中,仅当显式注册模板(例如,使用ZCML或Grok指令)时,才可以自定义模板TTW(通过portal_view_customizations )。

If you define template only in your __call__ , you won't see it in portal_view_customizations . 如果仅在__call__定义模板,则不会在portal_view_customizations看到它。

Also, I'd guess that loading template within a method would reload it from the disk for every view instance (every request). 另外,我猜想在方法中加载模板会为每个视图实例(每个请求)从磁盘重新加载它。

Note: To be fully equivalent to ZCML you should set the index variable to specify which template you are using. 注意:要完全等效于ZCML,您应该设置index变量以指定要使用的模板。 That way the TTW customization will work too. 这样,TTW定制也将起作用。

# foo.py
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.publisher.browser import BrowserPage
class FooView(BrowserPage):
    index = ViewPageTemplateFile('foo.pt')

One other pattern you can use with a browser view is adding an update method. 您可以在浏览器视图中使用的另一种模式是添加更新方法。

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

    def update(self):
        self.portal_catalog = ...  # initialize code

But this is not the question. 但这不是问题。


So what is the difference? 那么区别是什么呢? There is no difference . 没有区别 A browser view must be a callable. 浏览器视图必须是可调用的。 The ZCML directive builds this callable in a way the object has an index which must return the rendered page. ZCML指令以对象具有必须返回渲染页面的索引的方式构建此可调用对象。

But creating the template on each call (your example) there is one difference: you are creating a new instance of the template on each call of the browser view. 但是在每个调用上创建模板(您的示例)有一个区别:您正在浏览器视图的每个调用上创建模板的新实例。 This is not the case with class variable. 类变量不是这种情况。

One last option: You don't need a class argument in the directive 最后一个选择:指令中不需要类参数

<configure xmlns:browser="http://namespaces.zope.org/browser">
  <browser:page
    …
    template="foo.pt"
    …
    />
</configure>

For more information, you should read the code of the directive , which uses SimpleViewClass where src is the template name . 有关更多信息,您应该阅读该指令的代码,该指令使用SimpleViewClass,其中src是模板名称

AFAIK, there is no difference . AFAIK, 没有区别 The ZCML directive generates a ViewClass with a ViewPageTemplateFile and renders the template on a __call__ . ZCML指令使用ViewPageTemplateFile生成ViewPageTemplateFile并将模板呈现在__call__ See zope.browserpage.metaconfigure.page lines 132, 151. 参见zope.browserpage.metaconfigure.page行。

That is exactly the same you do in your example: you explicitly instantiate the template in your __call__ method. 这与您在示例中所做的完全相同:您在__call__方法中显式实例化了模板。

As to the subquestion: From my understanding, the significant differences are not apparent in the context of Zope2/Plone. 关于子问题:据我了解,在Zope2 / Plone的上下文中,没有明显的区别。 Based on the interface ( zope.publisher.interfaces.browser.IBrowserPage ), the BrowserPage is the base class you want to inherit from, since it implements __call__ and browserDefault . 基于接口( zope.publisher.interfaces.browser.IBrowserPage ),BrowserPage是要继承的基类,因为它实现了__call__browserDefault Yet, it does not seem to matter if you use BrowserPage or BrowserView with Plone. 但是,将BrowserPageBrowserView与Plone一起使用似乎并不重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM