Skip to content

Instantly share code, notes, and snippets.

@avoinea avoinea/dynamic_schema.py
Last active Dec 4, 2019

Embed
What would you like to do?
""" Custom Add/Edit forms
"""
from zope import schema
from zope.component import queryAdapter
from zope.component import provideAdapter
from z3c.form.browser.checkbox import CheckBoxFieldWidget
from z3c.form.browser.radio import RadioFieldWidget
from plone.dexterity.browser import edit
from plone.dexterity.browser import add
from eea.facetednavigation.interfaces import ICriteria
from plone.supermodel.model import Fieldset
from plone.supermodel.model import Schema
from plone.supermodel.model import SchemaClass
from plone.supermodel.interfaces import FIELDSETS_KEY
from plone.autoform.interfaces import WIDGETS_KEY
from my.policy.interfaces import IMagicContent
from my.policy import _
def getFacetedSchemata(context):
""" Compute Schemata from faceted criteria
"""
criteria = queryAdapter(context, ICriteria)
if not criteria:
return
fields = []
widgets = {}
for criterion in criteria.values():
if criterion.hidden:
continue
if criterion.section != 'advanced':
continue
widget = criterion.widget
if widget not in ['range', 'checkbox', 'multiselect', 'radio', 'select']:
continue
name = criterion.index.encode('utf-8')
if not name or name in ('path',):
continue
title = description = criterion.title
vocabulary = criterion.vocabulary
field = None
# Range
if widget == "range":
field = schema.Int(
title=title,
description=description,
required=True
)
# Checkbox
if widget == "checkbox":
operator = criterion.operator
if operator == 'and':
widgets[name] = CheckBoxFieldWidget
field = schema.List(
title=title,
description=description,
value_type=schema.Choice(
vocabulary=vocabulary,
),
required=True,
)
else:
widgets[name] = RadioFieldWidget
# MultiSelect
if widget == "multiselect":
operator = criterion.operator
if operator == 'and':
field = schema.Set(
title=title,
description=description,
value_type=schema.Choice(
vocabulary=vocabulary,
),
required=True,
)
# Radio
if widget == "radio":
widgets[name] = RadioFieldWidget
# Other
if not field:
field = schema.Choice(
title=title,
description=description,
vocabulary=vocabulary,
required=True,
)
fields.append((name, field))
schemaclass = SchemaClass(
'my.policy.faceted', (Schema, ),
__module__='my.policy.views.form',
attrs=dict(fields)
)
names = [f[0] for f in fields]
schemaclass.setTaggedValue(FIELDSETS_KEY, [
Fieldset(
'features',
label=_(u'Features'),
fields=names
)
])
schemaclass.setTaggedValue(WIDGETS_KEY, widgets)
if not queryAdapter(context, schemaclass):
provideAdapter(Mutator, (IMagicContent,), schemaclass)
yield schemaclass
class Mutator(object):
""" Generic mutator
"""
def __init__(self, context):
self.__dict__['context'] = context
def __setattr__(self, name, value):
setattr(self.context, name, value)
def __getattr__(self, name):
return getattr(self.context, name, None)
class EditForm(edit.DefaultEditForm):
""" Custom edit form """
@property
def additionalSchemata(self):
tabs = 0
for schemata in super(EditForm, self).additionalSchemata:
yield schemata
# Insert faceted schemata as the second tab
tabs += 1
if tabs == 1:
for schemata in getFacetedSchemata(self.context.getParentNode()):
yield schemata
class AddForm(add.DefaultAddForm):
portal_type = 'magic'
@property
def additionalSchemata(self):
tabs = 0
for schemata in super(AddForm, self).additionalSchemata:
yield schemata
# Insert faceted schemata as the second tab
tabs += 1
if tabs == 1:
for schemata in getFacetedSchemata(self.context):
yield schemata
class AddView(add.DefaultAddView):
form = AddForm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.