I have the special case of a conditional field in my dexterity content type at the moment. The parent object has an attribute (bool, yes/no) and I need to show/hide a field in the child content type depending on this (parent)attribute. In AT Types there was a condition-attribute on the field to handle something like that, but I couldn't figure out a way in dx.
There is perhaps (some complex) way to solve this on the Python layer however I do prefer Javascript
hackery here. What we usually do in such situations is having a viewlet that injects additional markup with data-attributes (in this case the information from the parent object) into the HTML of the Plone site and then some custom JS doing the hide/no-hide magic based on the value of such a data attribute...makes sense?
Should this happen in a normal View or on creation in the add/edit form?
You can traverse up to site root or only to the parent and check the property or behavior. If the boolvalue is 'True' do what you want in your child. But i don't know how "expensive" is that way.
# traverse up
# from plone.app.layout root.py
def getNavigationRootObject(context, portal):
obj = context
while not INavigationRoot.providedBy(obj) and aq_base(obj) is not aq_base(portal):
parent = aq_parent(aq_inner(obj))
if parent is None:
return obj
obj = parent
return obj
Since the appearance of your field is not dependent on another field in the same form, you could override the add/edit form and see if you can mess around with with the schema's a bit. Or maybe swapping out the widget for the field with a 'no display/null)' version of the widget based on the field value of the parent will be enough so you don't have to touch the schema as well.
Dexterity content types are dynamic in the sense that you can (re)define them through the web, but the changeability on a single instance is not well deveoped and/or documented with easy options, you have to go deep into dexterity itself.
from plone.dexterity.browser import add
class AddForm(add.DefaultAddForm):
portal_type = 'foo'
def updateWidgets(self):
super(AddForm, self).updateWidgets()
if getattr(self.context, 'whatever', None):
self.widgets['description'].mode = 'hidden'
class AddView(add.DefaultAddView):
form = AddForm