I want to customize the wrapper template (layout.pt from p.a.z3cform) for my dexterity content types but not the default Plone items. I am already able to do this by creating a browser view for 'edit' registered for my ICustomItems. This was just one zcml directive.
For the 'add' views, I am using adapters. However, I have many custom types and I had to register an 'add' adapter for each one like below:
I do not need to customize any other feature except their wrapper template.
For most templates, they can be overridden via z3c.jbot but this does not work for p.a.z3cform wrapper templates (layout.pt, form.pt, etc.). The package p.a.z3cform overrode layout.pt from p.z3cform via an adapter zcml directive:
<adapter factory=".views.layout_factory" />
What other attributes and values do I need to use in my adapter zcml configuration?
I will be trying things out but I would appreciate assistance if somebody has done the same already.
I am using Plone 6.0.13 ClassicUI with Python 3.12.5
You need a more specific layer for the layout_factory. But plone.app.z3cform.interfaces.IPloneFormLayer is very specific in the view/form context. You can add custom browserlayer interface in the add view to the form via alsoProvides, but then you need the custom add form definition from above.
Thank you for the information. I am now able to change the default wrapper form (p.a.z3cform.layout.pt) for the add and edit views for ALL content types. The code and configuration below made it work:
from plone.app.z3cform.interfaces import IPloneFormLayer
from zope.publisher.interfaces.browser import IDefaultBrowserLayer
class IMyThemeLayer(IDefaultBrowserLayer, IPloneFormLayer):
"""Marker interface that defines a browser layer."""
What remains is how to make the custom wrapper only work for some content types.
I looked at some of my code, and noticed that I had written:
<!-- note: Name must be same as content type -->
<adapter
factory=".views.MeetingAddFormView"
provides="zope.publisher.interfaces.browser.IBrowserPage"
for="*
DocentIMS.ActionItems.interfaces.IMyAddonLayer
plone.dexterity.interfaces.IDexterityFTI"
name="Meeting"
/>
from plone.app.z3cform.interfaces import IPloneFormLayer
from zope.publisher.interfaces.browser import IDefaultBrowserLayer
class IMyThemeLayer(IDefaultBrowserLayer, IPloneFormLayer):
"""Marker interface that defines a browser layer."""
browser/my_content.py
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from plone.dexterity.browser.add import DefaultAddForm
from plone.dexterity.browser.add import DefaultAddView
from plone.dexterity.browser.edit import DefaultEditForm
from plone.dexterity.browser.edit import DefaultEditView
class MyEditForm(DefaultEditForm):
""" MyTheme edit form """
class MyEditView(DefaultEditView):
""" MyTheme edit form view """
form = MyEditForm
class MyAddForm(DefaultAddForm):
""" MyTheme add form """
# portal_type = "My Type"
class MyAddView(DefaultAddView):
""" MyTheme add view """
form = MyAddForm
index = ViewPageTemplateFile("my_content.pt")
browser/layout.py
(same as my earlier post)
Notes:
My custom types have marker interfaces similar to dexterity (content, container, and item)
I did not use different FTI id and title in my custom types so I can get away with a single adapter registration for my add view. Otherwise, I will need a separate adapter registration for that particular type and I would need to add the portal_type attribute in its add form class.