def add(form, *args, **kwargs): """Add one or more fields. Keyword argument 'index' can be used to specify an index to insert at. Keyword argument 'group' can be used to specify the label of a group, which will be found and used or created if it doesn't exist. """ index = kwargs.pop('index', None) group = kwargs.pop('group', None) new_fields = Fields(*args, **kwargs) if not group or isinstance(group, basestring): source = find_source(form, group=group) else: source = group if source is None and group: source = GroupFactory(group, new_fields) form.groups.append(source) else: if index is None or index >= len(source.fields): source.fields += new_fields else: field_names = source.fields.keys() source.fields = source.fields.select(*field_names[:index]) + \ new_fields + \ source.fields.select(*field_names[index:])
def updateFieldsFromSchemata(self): self.groups = [] for name, schema in self.group_schemas: if name == '': continue # default, we don't need another group title = self.group_titles.get(name, name) fieldset_group = GroupFactory(name, field.Fields(), title) self.groups.append(fieldset_group) super(ComposedForm, self).updateFieldsFromSchemata()
def updateFieldsFromSchemata(self): # If the form is called from the ++widget++ traversal namespace, # we won't have a user yet. In this case, we can't perform permission # checks. have_user = bool(self.request.get('AUTHENTICATED_USER', False)) # Turn fields into an instance variable, since we will be modifying it self.fields = field.Fields(self.fields) # Copy groups to an instance variable and ensure that we have # the more mutable factories, rather than 'Group' subclasses groups = [] for g in self.groups: group_name = getattr(g, '__name__', g.label) fieldset_group = GroupFactory(group_name, field.Fields(g.fields), g.label, getattr(g, 'description', None)) groups.append(fieldset_group) # Copy to instance variable only after we have potentially read from # the class self.groups = groups prefixes = {} # Set up all widgets, modes, omitted fields and fieldsets if self.schema is not None: processFields(self, self.schema, permissionChecks=have_user) for schema in self.additionalSchemata: # Find the prefix to use for this form and cache for next round prefix = self.getPrefix(schema) if prefix and prefix in prefixes: prefix = schema.__identifier__ prefixes[schema] = prefix # By default, there's no default group, i.e. fields go # straight into the default fieldset defaultGroup = None # Create groups from schemata if requested and set default # group if self.autoGroups: # use interface name, or prefix for anonymous schema group_name = schema.__name__ or prefix or None # Look for group - note that previous processFields # may have changed the groups list, so we can't easily # store this in a dict. found = False for g in self.groups: if group_name == getattr(g, '__name__', g.label): found = True break if not found: fieldset_group = GroupFactory(group_name, field.Fields(), group_name, schema.__doc__) self.groups.append(fieldset_group) defaultGroup = group_name processFields(self, schema, prefix=prefix, defaultGroup=defaultGroup, permissionChecks=have_user) # Then process relative field movements. The base schema is processed # last to allow it to override any movements made in additional # schemata. if self.schema is not None: for schema in self.additionalSchemata: processFieldMoves(self, schema, prefix=prefixes[schema]) processFieldMoves(self, self.schema)
def _process_fieldsets(form, schema, groups, all_fields, prefix, default_group): """ Keep track of which fields are in a fieldset, and, by elimination, which ones are not """ # { name => e.g. 'hidden' } modes = mergedTaggedValuesForForm(schema, MODES_KEY, form) # { name => widget/dotted name } widgets = mergedTaggedValueDict(schema, WIDGETS_KEY) # list of IFieldset instances fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY) # process primary schema fieldsets fieldset_fields = [] for fieldset in fieldsets: for field_name in fieldset.fields: fieldset_fields.append(_process_prefixed_name(prefix, field_name)) # Set up the default fields, widget factories and widget modes new_fields = all_fields.omit(*fieldset_fields) _process_widgets(form, widgets, modes, new_fields) if not default_group: form.fields += new_fields else: groups[default_group].fields += new_fields # Set up fields for fieldsets for fieldset in fieldsets: new_fields = all_fields.select(*[ _process_prefixed_name(prefix, name) for name in fieldset.fields if _process_prefixed_name(prefix, name) in all_fields ]) if fieldset.__name__ in groups: # Process also, if no fields are defined to allow fieldset-only # configurations via plone.supermodel fieldset directive. group = groups[fieldset.__name__] group.fields += new_fields if (fieldset.label and group.label != fieldset.label and group.__name__ != fieldset.label # defaults to name! ): group.label = fieldset.label if (fieldset.description and group.description != fieldset.description): group.description = fieldset.description if (fieldset.order and fieldset.order != DEFAULT_ORDER and fieldset.order != group.order): group.order = fieldset.order if len(new_fields) > 0 or getattr(form, 'showEmptyGroups', False): _process_widgets(form, widgets, modes, new_fields) if fieldset.__name__ not in groups: group = GroupFactory(fieldset.__name__, label=fieldset.label, description=fieldset.description, order=fieldset.order, fields=new_fields) form.groups.append(group) groups[group.__name__] = group
def processFields(form, schema, prefix='', defaultGroup=None, permissionChecks=True): """Add the fields from the schema to the form, taking into account the hints in the various tagged values as well as fieldsets. If prefix is given, the fields will be prefixed with this prefix. If defaultGroup is given (as a Fieldset instance), any field not explicitly placed into a particular fieldset, will be added to the given group, which must exist already. If permissionChecks is false, permission checks are ignored. """ # Get data from tagged values, flattening data from super-interfaces # Note: The names always refer to a field in the schema, and never # contain a prefix. # { name => True } omitted = mergedTaggedValuesForForm(schema, OMITTED_KEY, form) # { name => e.g. 'hidden' } modes = mergedTaggedValuesForForm(schema, MODES_KEY, form) # { name => widget/dotted name } widgets = mergedTaggedValueDict(schema, WIDGETS_KEY) # list of IFieldset instances fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY) # Get either read or write permissions depending on what type of # form this is readPermissions = {} # field name -> permission name writePermissions = {} # field name -> permission name permissionCache = {} # permission name -> allowed/disallowed if permissionChecks: # name => permission name readPermissions = mergedTaggedValueDict( schema, READ_PERMISSIONS_KEY ) # name => permission name writePermissions = mergedTaggedValueDict( schema, WRITE_PERMISSIONS_KEY ) securityManager = getSecurityManager() # Find the fields we should not worry about groups = {} doNotProcess = list(form.fields.keys()) for fieldName, status in omitted.items(): if status and status != 'false': doNotProcess.append(_fn(prefix, fieldName)) for group in form.groups: doNotProcess.extend(list(group.fields.keys())) groupName = getattr(group, '__name__', group.label) groups[groupName] = group # Find all allowed fields so that we have something to select from omitReadOnly = form.mode != DISPLAY_MODE allFields = field.Fields( schema, prefix=prefix, omitReadOnly=omitReadOnly ).omit(*doNotProcess) # Check permissions if permissionChecks: disallowedFields = [] for fieldName, fieldInstance in allFields.items(): fieldName = fieldInstance.__name__ fieldMode = fieldInstance.mode or form.mode permissionName = None if fieldMode == DISPLAY_MODE: permissionName = readPermissions.get(_bn(fieldInstance), None) elif fieldMode == INPUT_MODE: permissionName = writePermissions.get(_bn(fieldInstance), None) if permissionName is not None: if permissionName not in permissionCache: permission = queryUtility(IPermission, name=permissionName) if permission is None: permissionCache[permissionName] = True else: permissionCache[permissionName] = bool( securityManager.checkPermission( permission.title, form.context ) ) if not permissionCache.get(permissionName, True): disallowedFields.append(fieldName) allFields = allFields.omit(*disallowedFields) # Keep track of which fields are in a fieldset, and, by elimination, # which ones are not fieldsetFields = [] for fieldset in fieldsets: for fieldName in fieldset.fields: fieldsetFields.append(_fn(prefix, fieldName)) # Set up the default fields, widget factories and widget modes newFields = allFields.omit(*fieldsetFields) _processWidgets(form, widgets, modes, newFields) if not defaultGroup: form.fields += newFields else: groups[defaultGroup].fields += newFields # Set up fields for fieldsets for fieldset in fieldsets: newFields = allFields.select(*[_fn(prefix, fieldName) for fieldName in fieldset.fields if _fn(prefix, fieldName) in allFields]) if getattr(form, 'showEmptyGroups', False) or (len(newFields) > 0): _processWidgets(form, widgets, modes, newFields) if fieldset.__name__ not in groups: group = GroupFactory(fieldset.__name__, label=fieldset.label, description=fieldset.description, fields=newFields) form.groups.append(group) groups[group.__name__] = group else: groups[fieldset.__name__].fields += newFields
def _process_fieldsets( form, schema, groups, all_fields, prefix, default_group ): """ Keep track of which fields are in a fieldset, and, by elimination, which ones are not """ # { name => e.g. 'hidden' } modes = mergedTaggedValuesForForm(schema, MODES_KEY, form) # { name => widget/dotted name } widgets = mergedTaggedValueDict(schema, WIDGETS_KEY) # list of IFieldset instances fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY) # process primary schema fieldsets fieldset_fields = [] for fieldset in fieldsets: for field_name in fieldset.fields: fieldset_fields.append(_process_prefixed_name(prefix, field_name)) # Set up the default fields, widget factories and widget modes new_fields = all_fields.omit(*fieldset_fields) _process_widgets(form, widgets, modes, new_fields) if not default_group: form.fields += new_fields else: groups[default_group].fields += new_fields # Set up fields for fieldsets for fieldset in fieldsets: new_fields = all_fields.select( *[_process_prefixed_name(prefix, name) for name in fieldset.fields if _process_prefixed_name(prefix, name) in all_fields] ) if not ( getattr(form, 'showEmptyGroups', False) or len(new_fields) > 0 ): continue _process_widgets(form, widgets, modes, new_fields) if fieldset.__name__ not in groups: group = GroupFactory(fieldset.__name__, label=fieldset.label, description=fieldset.description, order=fieldset.order, fields=new_fields) form.groups.append(group) groups[group.__name__] = group else: group = groups[fieldset.__name__] group.fields += new_fields if ( fieldset.label and group.label != fieldset.label and group.__name__ != fieldset.label # defaults to name! ): group.label = fieldset.label if ( fieldset.description and group.description != fieldset.description ): group.description = fieldset.description if ( fieldset.order and fieldset.order != DEFAULT_ORDER and fieldset.order != group.order ): group.order = fieldset.order