我创建了一个自定义内容类型( Resume ),我希望提供一个自定义的“编辑”视图。我的用例非常简单,我只想在编辑表单之前显示一个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
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.xml 中“编辑”的默认别名:
<alias from="edit" to="resume_edit" />
安装后,添加或编辑Resume内容类型会引发此异常:
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'
如何解决此问题并为我的内容类型的编辑视图提供自己的自定义模板?
答案 0 :(得分:6)
我建议不要复制atct_edit.cpt。您真正需要做的就是配置一个编辑模板(看起来你知道该怎么做),然后覆盖相应的部分。有关详细信息,请参阅文档here。
另外,我首先要使用完全空白的编辑模板。然后在其中放入一些有效的XHTML,例如&lt; span&gt; Hello world!&lt; / span&gt;并确保您可以通过单击编辑按钮加载编辑模板。
答案 1 :(得分:3)
要跟进alex的答案:如果您不反对额外的依赖项,替代解决方案也可以通过z3c.form / plone.autoform提供您自己的编辑表单。有关基本介绍/想法,请参阅this manual。
答案 2 :(得分:3)
您必须使用Viewlet来实现此目的。
为每个视图注册一个viewlet,对渲染调用进行一些检查,然后显示你想要的内容。
因此您无需重新创建表单