[英]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. 但是,将
BrowserPage
或BrowserView
与Plone一起使用似乎并不重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.