Plone 4 中的自定义编辑视图
我创建了自定义内容类型(简历),并且希望提供自定义“编辑”视图。我的用例非常简单,我只想在编辑表单之前显示一个 HTML“免责声明”框。
首先,我将:复制
Products/ATContentTypes/skins/ATContentTypes/atct_edit.cpt
Products/ATContentTypes/skins/ATContentTypes/atct_edit.cpt.metadata
到 my/product/browser/ 中,
my/product/browser/resumeedit.cpt
my/product/browser/resumeedit.cpt.metadata
然后我在 my/product/browser/configure.zcml 中定义了一个新的 browser:page 节:
<browser:page
for="..interfaces.IResume"
name="resume_edit"
class=".resumeview.ResumeEdit"
template="resumeedit.cpt"
permission="cmf.ModifyPortalContent"
/>
my/product/browser/resumeview.py 中的简历类很简单:
class ResumeEdit(BrowserView):
""" A customization of the Resume Edit form
"""
__call__ = ViewPageTemplateFile('resumeedit.cpt')
最后,我更改了 my/product/profiles/default/types/Resume 中“edit”的默认别名.xml:
<alias from="edit" to="resume_edit" />
安装后,添加或编辑简历内容类型会引发此异常:
Unauthorized: The container has no security assertions. Access to 'id' of (Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x1e8b7a50) denied.
通过提供 edit_macros.pt 的修补版本可以缓解此问题:
85c85
< tal:attributes="action python:context.absolute_url()+'/'+template.id;
---
> tal:attributes="action python:context.absolute_url()+'/'+path('template/getId|nothing');
203c203
< tal:attributes="value python:(last_referer and '%s/%s' % (context.absolute_url(), template.id) not in last_referer) and last_referer or (context.getParentNode() and context.getParentNode().absolute_url())"
---
> tal:attributes="value python:(last_referer and '%s/%s' % (context.absolute_url(), path('template/getId|nothing')) not in last_referer) and last_referer or (context.getParentNode() and context.getParentNode().absolute_url())"
不过,这会引发以下异常(' id-64121786'是我的简历项目的id):
Module zope.tales.tales, line 696, in evaluate
- URL: file:/home/zope/env26/plone-devel/eggs/Products.Archetypes-1.6.5-py2.6.egg/Products/Archetypes/skins/archetypes/widgets/field.pt
- Line 63, Column 4
- Expression: <PythonExpr errors.get(fieldName)>
- Names:
{'args': (),
'container': <Resume at /cms/id-64121786>,
'context': <Resume at /cms/id-64121786>,
'default': <object object at 0x8e094c0>,
'here': <Resume at /cms/id-64121786>,
'loop': {},
'nothing': None,
'options': {},
'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x126e7470>,
'request': <HTTPRequest, URL=http://localhost:8081/cms/id-64121786/resume_edit>,
'root': <Application at >,
'template': <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x117da910>,
'traverse_subpath': [],
'user': <PloneUser 'admin'>,
'view': <Products.Five.metaclass.SimpleViewClass from /home/zope/env26/plone-devel/src/my.product/my/product/browser/resumeedit.cpt object at 0x126d8c90>,
'views': <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x126d8fd0>}
Module Products.PageTemplates.ZRPythonExpr, line 49, in __call__
- __traceback_info__: errors.get(fieldName)
Module PythonExpr, line 1, in <expression>
Module AccessControl.ImplPython, line 688, in guarded_getattr
AttributeError: 'NoneType' object has no attribute 'get'
我如何解决这个问题并为我的内容类型的编辑视图提供我自己的自定义模板?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我建议不要复制 atct_edit.cpt。您真正需要做的就是配置一个编辑模板(看起来您知道如何做),然后覆盖适当的部分。请参阅文档 此处了解更多信息。
另外,我会首先从一个完全空白的编辑模板开始。然后在其中放入一些有效的 XHTML,例如 Hello world!并确保您可以通过单击编辑按钮加载编辑模板。
I would suggest not copying atct_edit.cpt. All you really need to do is configure an edit template (which it looks like you know how to do) then override the appropriate parts. See documentation here for more information.
Also, I would start with a completely blank edit template first. Then put some valid XHTML in it e.g. <span>Hello world!</span> and make sure you can load the edit template by clicking on the edit button.
跟进亚历克斯的回答:如果您不反对额外的依赖项,另一种解决方案也可以通过 z3c.form/plone.autoform 提供您自己的编辑表单。请参阅本手册了解基本介绍/想法。
To follow up on alex's answer: an alternative solution could also be providing your own edit form via z3c.form/plone.autoform if you don't object against the extra dependencies. See this manual for the basic introduction/idea.
您必须使用视图来实现此目的。
为每个视图注册一个视图,对渲染调用进行一些检查以显示您想要的内容。
所以你不必重新创建表单
You must use a viewlet to achieve this.
Register a viewlet for every views, make some check on rendering call display what every you want.
So you don't have to recreate the form