Example #1
0
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:])
Example #2
0
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:])
Example #3
0
 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()
Example #4
0
    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)
Example #5
0
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
Example #6
0
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
Example #7
0
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