Ejemplo n.º 1
0
    def validate(self, values):
        if values is None:
            return super(VocabularyValuesValidator, self).validate(values)

        by_value = {}
        by_token = {}
        for value in values:
            term = vocabulary.SimpleTerm(token=value.encode('unicode_escape'),
                                         value=value,
                                         title=value)
            if term.value in by_value:
                raise interface.Invalid(
                    _('field_edit_error_conflicting_values',
                      default=
                      u"The '${value1}' vocabulary value conflicts with '${value2}'.",
                      mapping={
                          'value1': value,
                          'value2': by_value[term.value].value
                      }))

            if term.token in by_token:
                raise interface.Invalid(
                    _('field_edit_error_conflicting_values',
                      default=
                      u"The '${value1}' vocabulary value conflicts with '${value2}'.",
                      mapping={
                          'value1': value,
                          'value2': by_value[term.token].value
                      }))

            by_value[term.value] = term
            by_token[term.token] = term

        return super(VocabularyValuesValidator, self).validate(values)
Ejemplo n.º 2
0
    def validate(self, values):
        if values is None:
            return super(VocabularyValuesValidator, self).validate(
                values)

        by_value = {}
        by_token = {}
        for value in values:
            term = vocabulary.SimpleTerm(token=value.encode('unicode_escape'),
                                         value=value, title=value)
            if term.value in by_value:
                raise interface.Invalid(
                    _('field_edit_error_conflicting_values',
                      default=u"The '${value1}' vocabulary value conflicts with '${value2}'.",
                      mapping={'value1': value,
                               'value2': by_value[term.value].value}))

            if term.token in by_token:
                raise interface.Invalid(
                    _('field_edit_error_conflicting_values',
                      default=u"The '${value1}' vocabulary value conflicts with '${value2}'.",
                      mapping={'value1': value,
                               'value2': by_value[term.token].value}))

            by_value[term.value] = term
            by_token[term.token] = term

        return super(VocabularyValuesValidator, self).validate(values)
Ejemplo n.º 3
0
 def label(self):
     if self.context.Title() != self.context.__name__:
         return _(u'Edit ${title} (${name})',
                  mapping={'title': self.context.Title(),
                           'name': self.context.__name__})
     else:
         return _(u'Edit ${name}', mapping={'name': self.context.__name__})
 def checkTitleAndDescriptionTypes(data):
     if data.__name__ is not None and data.factory is not None:
         if data.__name__ == 'title' and data.factory.fieldcls is not TextLine:
             raise Invalid(
                 _(u"The 'title' field must be a Text line (string) field."))
         if data.__name__ == 'description' and data.factory.fieldcls is not Text:
             raise Invalid(
                 _(u"The 'description' field must be a Text field."))
def isValidFieldName(value):
    if not ID_RE.match(value):
        raise Invalid(
            _(u'Please use only letters, numbers and the following characters: _.'))
    if value in RESERVED_NAMES:
        raise Invalid(
            _(u"'${name}' is a reserved field name.", mapping={'name': value}))
    return True
Ejemplo n.º 6
0
 def checkTitleAndDescriptionTypes(data):
     if data.__name__ is not None and data.factory is not None:
         if data.__name__ == 'title' and data.factory.fieldcls is not TextLine:
             raise Invalid(
                 _(u"The 'title' field must be a Text line (string) field."))
         if data.__name__ == 'description' and data.factory.fieldcls is not Text:
             raise Invalid(
                 _(u"The 'description' field must be a Text field."))
Ejemplo n.º 7
0
def isValidFieldName(value):
    if not ID_RE.match(value):
        raise Invalid(
            _(u'Please use only letters, numbers and the following characters: _.'))
    if value in RESERVED_NAMES:
        raise Invalid(
            _(u"'${name}' is a reserved field name.", mapping={'name': value}))
    return True
Ejemplo n.º 8
0
 def label(self):
     if self.context.Title() != self.context.__name__:
         return _(u'Edit ${title} (${name})',
                  mapping={
                      'title': self.context.Title(),
                      'name': self.context.__name__
                  })
     else:
         return _(u'Edit ${name}', mapping={'name': self.context.__name__})
Ejemplo n.º 9
0
 def add(self, field):
     schema = IEditableSchema(self.context.schema)
     try:
         schema.addField(field)
     except ValueError:
         raise WidgetActionExecutionError('__name__',
             Invalid(_(u'Please select a field name that is not already used.')))
     notify(ObjectAddedEvent(field, self.context.schema))
     notify(SchemaModifiedEvent(self.context))
     self.status = _(u"Field added successfully.")
Ejemplo n.º 10
0
class INewFieldset(Interface):

    label = TextLine(title=_(u'Title'), required=True)

    __name__ = ASCIILine(
        title=_(u'Short Name'),
        description=_(u'Used for programmatic access to the fieldset.'),
        required=True,
        constraint=isValidFieldName,
    )
Ejemplo n.º 11
0
    def add(self, new_fieldset):
        schema = self.context.schema
        fieldsets = schema.getTaggedValue(FIELDSETS_KEY)

        for fieldset in fieldsets:
            if fieldset.__name__ == new_fieldset.__name__:
                raise WidgetActionExecutionError('__name__',
                    Invalid(_(u'Please select a fieldset name that is not already used.')))

        fieldsets.append(new_fieldset)
        schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
        notifyContainerModified(schema)
        notify(SchemaModifiedEvent(self.context))
        self.status = _(u"Fieldset added successfully.")
Ejemplo n.º 12
0
    def label(self):
        """ In a dexterity schema editing context, we need to
            construct a label that will specify the field being
            edited. Outside that context (e.g., plone.app.users),
            we should respect the label if specified.
        """

        context_label = getattr(self.context, "label", None)
        if context_label is not None:
            return context_label
        if self.context.Title() != self.context.__name__:
            return _(u"Edit ${title} (${name})", mapping={"title": self.context.Title(), "name": self.context.__name__})
        else:
            return _(u"Edit ${name}", mapping={"name": self.context.__name__})
    def __call__(self):
        """Handle AJAX save post.
        """

        if not authorized(self.context, self.request):
            raise Unauthorized

        source = self.request.form.get('source')
        if source:
            # Is it valid XML?
            try:
                root = etree.fromstring(source)
            except etree.XMLSyntaxError, e:
                return json.dumps({
                    'success':
                    False,
                    'message':
                    "XMLSyntaxError: %s" % e.message.encode('utf8')
                })

            # a little more sanity checking, look at first two element levels
            if root.tag != NAMESPACE + 'model':
                return json.dumps({
                    'success':
                    False,
                    'message':
                    _(u"Error: root tag must be 'model'")
                })
            for element in root.getchildren():
                if element.tag != NAMESPACE + 'schema':
                    return json.dumps({
                        'success':
                        False,
                        'message':
                        _(u"Error: all model elements must be 'schema'")
                    })

            # can supermodel parse it?
            # This is mainly good for catching bad dotted names.
            try:
                plone.supermodel.loadString(source, policy=u"dexterity")
            except SupermodelParseError, e:
                message = e.args[0].replace('\n  File "<unknown>"', '')
                return json.dumps({
                    'success':
                    False,
                    'message':
                    u"SuperModelParseError: %s" % message
                })
class FieldsetAddForm(form.AddForm):

    fields = field.Fields(INewFieldset)
    label = _('Add new fieldset')
    id = 'add-fieldset-form'

    def create(self, data):
        return Fieldset(**data)

    def add(self, new_fieldset):
        schema = self.context.schema
        fieldsets = schema.queryTaggedValue(FIELDSETS_KEY, [])

        for fieldset in fieldsets:
            if fieldset.__name__ == new_fieldset.__name__:
                msg = _(
                    u'Please select a fieldset name that is not already used.'
                )
                raise WidgetActionExecutionError(
                    '__name__',
                    Invalid(msg)
                )

        fieldsets.append(new_fieldset)
        schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
        notifyContainerModified(schema)
        notify(SchemaModifiedEvent(self.context))
        IStatusMessage(self.request).addStatusMessage(
            _(u'Fieldset added successfully.'), type='info')

    def nextURL(self):
        return '@@add-fieldset'
Ejemplo n.º 15
0
    def label(self):
        """ In a dexterity schema editing context, we need to
            construct a label that will specify the field being
            edited. Outside that context (e.g., plone.app.users),
            we should respect the label if specified.
        """

        context_label = getattr(self.context, 'label', None)
        if context_label is not None:
            return context_label
        if self.context.Title() != self.context.__name__:
            return _(u'Edit ${title} (${name})',
                     mapping={'title': self.context.Title(),
                              'name': self.context.__name__})
        else:
            return _(u'Edit ${name}', mapping={'name': self.context.__name__})
Ejemplo n.º 16
0
class FieldsetAddForm(form.AddForm):

    fields = field.Fields(INewFieldset)
    label = _("Add new fieldset")
    id = 'add-fieldset-form'

    def create(self, data):
        return Fieldset(**data)

    def add(self, new_fieldset):
        schema = self.context.schema
        fieldsets = schema.getTaggedValue(FIELDSETS_KEY)

        for fieldset in fieldsets:
            if fieldset.__name__ == new_fieldset.__name__:
                raise WidgetActionExecutionError('__name__',
                    Invalid(_(u'Please select a fieldset name that is not already used.')))

        fieldsets.append(new_fieldset)
        schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
        notifyContainerModified(schema)
        notify(SchemaModifiedEvent(self.context))
        self.status = _(u"Fieldset added successfully.")

    def nextURL(self):
        url = self.context.absolute_url()
        if getattr(self.context, 'schemaEditorView', None) is not None:
            url += '/@@' + self.context.schemaEditorView

        return url
Ejemplo n.º 17
0
    def add(self, field):
        context = self.context
        schema = IEditableSchema(context.schema)

        # move it after the last field that is not in a fieldset
        # or at top if there is no field yet in "default" fieldset
        ordered_fields = [name for (name, f) in sortedFields(context.schema)]
        default_fields = non_fieldset_fields(context.schema)
        if len(default_fields) > 0:
            position = ordered_fields.index(default_fields[-1]) + 1
        else:
            position = 0

        try:
            schema.addField(field)
        except ValueError:
            raise WidgetActionExecutionError('__name__',
                Invalid(
                    u'Please select a field name that is not already used.'
                ))

        schema.moveField(field.__name__, position)
        notify(ObjectAddedEvent(field, context.schema))
        notify(FieldAddedEvent(context, field))
        IStatusMessage(self.request).addStatusMessage(
            _(u"Field added successfully."), type='info')
Ejemplo n.º 18
0
class ITextLineChoice(interfaces.IField):

    values = schema.List(title=_(u'Possible values'),
                         description=_(u'Enter allowed choices one per line.'),
                         required=interfaces.IChoice['vocabulary'].required,
                         default=interfaces.IChoice['vocabulary'].default,
                         value_type=schema.TextLine())
    interface.alsoProvides(values, ITextLinesField)

    vocabularyName = schema.Choice(
        title=interfaces.IChoice['vocabularyName'].title,
        description=interfaces.IChoice['vocabularyName'].description,
        default=interfaces.IChoice['vocabularyName'].default,
        required=False,
        vocabulary="plone.schemaeditor.VocabulariesVocabulary",
    )
    def __call__(self):
        """Handle AJAX save post.
        """

        if not authorized(self.context, self.request):
            raise Unauthorized

        source = self.request.form.get('source')
        if source:
            # Is it valid XML?
            try:
                root = etree.fromstring(source)
            except etree.XMLSyntaxError, e:
                return json.dumps({
                    'success': False,
                    'message': "XMLSyntaxError: %s" % e.message.encode('utf8')
                })

            # a little more sanity checking, look at first two element levels
            if root.tag != NAMESPACE + 'model':
                return json.dumps({
                    'success': False,
                    'message': _(u"Error: root tag must be 'model'")
                })
            for element in root.getchildren():
                if element.tag != NAMESPACE + 'schema':
                    return json.dumps({
                        'success': False,
                        'message': _(
                            u"Error: all model elements must be 'schema'"
                        )
                    })

            # can supermodel parse it?
            # This is mainly good for catching bad dotted names.
            try:
                plone.supermodel.loadString(source, policy=u"dexterity")
            except SupermodelParseError, e:
                message = e.args[0].replace('\n  File "<unknown>"', '')
                return json.dumps({
                    'success': False,
                    'message': u"SuperModelParseError: %s" % message
                })
    def add(self, new_fieldset):
        schema = self.context.schema
        fieldsets = schema.queryTaggedValue(FIELDSETS_KEY, [])

        for fieldset in fieldsets:
            if fieldset.__name__ == new_fieldset.__name__:
                msg = _(
                    u'Please select a fieldset name that is not already used.'
                )
                raise WidgetActionExecutionError(
                    '__name__',
                    Invalid(msg)
                )

        fieldsets.append(new_fieldset)
        schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
        notifyContainerModified(schema)
        notify(SchemaModifiedEvent(self.context))
        IStatusMessage(self.request).addStatusMessage(
            _(u'Fieldset added successfully.'), type='info')
Ejemplo n.º 21
0
    def validate(self, values):
        if values is None:
            return super(VocabularyNameValidator, self).validate(values)

        if values and self.request.form.get('form.widgets.values', None):
            raise interface.Invalid(
                _('field_edit_error_values_and_name',
                  default=
                  u"You can't set a vocabulary name AND vocabulary values. "
                  u"Please clear values field or set no value here."))

        return super(VocabularyNameValidator, self).validate(values)
Ejemplo n.º 22
0
    def validate(self, values):
        if values is None:
            return super(VocabularyNameValidator, self).validate(
                values)

        if values and self.request.form.get('form.widgets.values', None):
            raise interface.Invalid(
                _('field_edit_error_values_and_name',
                  default=u"You can't set a vocabulary name AND vocabulary values. "
                          u"Please clear values field or set no value here."))

        return super(VocabularyNameValidator, self).validate(values)
Ejemplo n.º 23
0
class INewField(Interface):

    title = TextLine(title=_(u'Title'), required=True)

    __name__ = ASCIILine(
        title=_(u'Short Name'),
        description=_(u'Used for programmatic access to the field.'),
        required=True,
        constraint=isValidFieldName,
    )

    description = Text(
        title=_(u'Help Text'),
        description=_(u'Shows up in the form as help text for the field.'),
        required=False)

    factory = Choice(
        title=_(u"Field type"),
        vocabulary="Fields",
        required=True,
        # This can't be done yet or we'll create circular import problem.
        # So it will be injected from fields.py
        # default=TextLineFactory,
    )

    @invariant
    def checkTitleAndDescriptionTypes(data):
        if data.__name__ is not None and data.factory is not None:
            if data.__name__ == 'title' and data.factory.fieldcls is not TextLine:
                raise Invalid(
                    _(u"The 'title' field must be a Text line (string) field.")
                )
            if data.__name__ == 'description' and data.factory.fieldcls is not Text:
                raise Invalid(
                    _(u"The 'description' field must be a Text field."))
Ejemplo n.º 24
0
class FieldAddForm(form.AddForm):

    fields = field.Fields(INewField)
    label = _("Add new field")
    id = 'add-field-form'

    def create(self, data):
        factory = data.pop('factory')
        return factory(**data)

    def add(self, field):
        context = self.context
        schema = IEditableSchema(context.schema)

        # move it after the last field that is not in a fieldset
        # or at top if there is no field yet in "default" fieldset
        ordered_fields = [name for (name, f) in sortedFields(context.schema)]
        default_fields = non_fieldset_fields(context.schema)
        if len(default_fields) > 0:
            position = ordered_fields.index(default_fields[-1]) + 1
        else:
            position = 0

        try:
            schema.addField(field)
        except ValueError:
            raise WidgetActionExecutionError(
                '__name__',
                Invalid(
                    u'Please select a field name that is not already used.'))

        schema.moveField(field.__name__, position)
        notify(ObjectAddedEvent(field, context.schema))
        notify(FieldAddedEvent(context, field))
        self.status = _(u"Field added successfully.")

    def nextURL(self):
        url = self.context.absolute_url()
        if getattr(self.context, 'schemaEditorView', None) is not None:
            url += '/@@' + self.context.schemaEditorView
        return url
Ejemplo n.º 25
0
    def add(self, new_field):
        schema = self.context.schema
        fieldset_id = int(self.request.form.get('fieldset_id', 0))
        position = new_field_position(schema, fieldset_id)

        editable_schema = IEditableSchema(schema)
        try:
            editable_schema.addField(new_field)
        except ValueError:
            raise WidgetActionExecutionError(
                '__name__',
                Invalid(
                    u'Please select a field name that is not already used.'))
        if fieldset_id:
            fieldset = get_fieldset_from_index(schema, fieldset_id)
            editable_schema.changeFieldFieldset(new_field.__name__, fieldset)
        editable_schema.moveField(new_field.__name__, position)

        notify(ObjectAddedEvent(new_field, schema))
        notify(FieldAddedEvent(self.context, new_field))
        IStatusMessage(self.request).addStatusMessage(
            _(u'Field added successfully.'), type='info')
Ejemplo n.º 26
0
    def add(self, field):
        context = self.context
        schema = IEditableSchema(context.schema)

        # move it after the last field that is not in a fieldset
        # or at top if there is no field yet in "default" fieldset
        ordered_fields = [name for (name, f) in sortedFields(context.schema)]
        default_fields = non_fieldset_fields(context.schema)
        if len(default_fields) > 0:
            position = ordered_fields.index(default_fields[-1]) + 1
        else:
            position = 0

        try:
            schema.addField(field)
        except ValueError:
            raise WidgetActionExecutionError('__name__',
                Invalid(u'Please select a field name that is not already used.'))

        schema.moveField(field.__name__, position)
        notify(ObjectAddedEvent(field, context.schema))
        notify(FieldAddedEvent(context, field))
        self.status = _(u"Field added successfully.")
Ejemplo n.º 27
0
    def handleSave(self, action):
        data, errors = self.extractData()

        # For choice fields, make sure default is in the valid values
        if "values" in data:
            values = data["values"] or []
            if "default" in data and data["default"]:
                default = data["default"]
                if type(default) is not list:
                    default = [default]
                for value in default:
                    if value not in values:
                        raise WidgetActionExecutionError(
                            "default", Invalid(_(u"Please enter a valid vocabulary value."))
                        )

        if errors:
            self.status = self.formErrorsMessage
            return

        # clear current min/max to avoid range errors
        if "min" in data:
            self.field.min = None
        if "max" in data:
            self.field.max = None

        default = data.pop("default", _marker)
        changes = self.applyChanges(data)

        # make sure we can report invalid defaults
        if default is not _marker:
            try:
                changes2 = self.applyChanges({"default": default})
            except schema.ValidationError, e:
                raise WidgetActionExecutionError("default", e)
            else:
                changes = changes or changes2
Ejemplo n.º 28
0
    def add(self, new_field):
        schema = self.context.schema
        fieldset_id = int(self.request.form.get('fieldset_id', 0))
        position = new_field_position(schema, fieldset_id)

        editable_schema = IEditableSchema(schema)
        try:
            editable_schema.addField(new_field)
        except ValueError:
            raise WidgetActionExecutionError(
                '__name__',
                Invalid(
                    u'Please select a field name that is not already used.'
                )
            )
        if fieldset_id:
            fieldset = get_fieldset_from_index(schema, fieldset_id)
            editable_schema.changeFieldFieldset(new_field.__name__, fieldset)
        editable_schema.moveField(new_field.__name__, position)

        notify(ObjectAddedEvent(new_field, schema))
        notify(FieldAddedEvent(self.context, new_field))
        IStatusMessage(self.request).addStatusMessage(
            _(u'Field added successfully.'), type='info')
Ejemplo n.º 29
0
class FieldAddForm(AutoExtensibleForm, form.AddForm):

    fields = field.Fields(interfaces.INewField)
    label = _('Add new field')
    id = 'add-field-form'

    # This is a trick: we want autoform to handle the additionalSchemata,
    # but want to provide our own base schema below in updateFields.
    schema = Interface

    @lazy_property
    def _schema(self):
        return interfaces.INewField

    @lazy_property
    def additionalSchemata(self):
        return [
            v for k, v in getAdapters((
                self.context, ), interfaces.IFieldEditorExtender)
        ]

    def create(self, data):
        extra = {}
        factory = data.pop('factory')

        # split regular attributes and extra ones
        for key in data.keys():
            if key not in self._schema:
                extra[key] = data[key]
                data.pop(key)

        # create the field with regular attributes
        field_obj = factory(**data)

        # set the extra attributes using the proper adapter
        for schemata in self.additionalSchemata:
            for key in extra:
                (interface_name, property_name) = key.split('.')
                if interface_name != schemata.__name__:
                    continue
                setattr(schemata(field_obj), property_name, extra[key])

        return field_obj

    def add(self, new_field):
        schema = self.context.schema
        fieldset_id = int(self.request.form.get('fieldset_id', 0))
        position = new_field_position(schema, fieldset_id)

        editable_schema = IEditableSchema(schema)
        try:
            editable_schema.addField(new_field)
        except ValueError:
            raise WidgetActionExecutionError(
                '__name__',
                Invalid(
                    u'Please select a field name that is not already used.'))
        if fieldset_id:
            fieldset = get_fieldset_from_index(schema, fieldset_id)
            editable_schema.changeFieldFieldset(new_field.__name__, fieldset)
        editable_schema.moveField(new_field.__name__, position)

        notify(ObjectAddedEvent(new_field, schema))
        notify(FieldAddedEvent(self.context, new_field))
        IStatusMessage(self.request).addStatusMessage(
            _(u'Field added successfully.'), type='info')

    def updateWidgets(self):
        super(FieldAddForm, self).updateWidgets()
        fieldset_id = int(self.request.form.get('fieldset_id', 0))
        if fieldset_id:
            # add fieldset_id from GET parameter as hidden field, so that
            # ``add`` method at the end of the form lifecycle can read it.
            fieldset_id_widget = TextWidget(self.request)
            fieldset_id_widget.name = 'fieldset_id'
            fieldset_id_widget.value = fieldset_id
            fieldset_id_widget.mode = HIDDEN_MODE
            # Uhm. z3c.form widgets doesn't have an API for extending a
            # schema-generated form. Using internal ``_data_values``...
            self.widgets._data_values.append(fieldset_id_widget)

    def nextURL(self):
        return '@@add-field'
Ejemplo n.º 30
0
 def label(self):
     return _(u"Edit Field '${fieldname}'",
              mapping={'fieldname': self.field.__name__})
Ejemplo n.º 31
0
class FieldAddForm(AutoExtensibleForm, form.AddForm):

    fields = field.Fields(interfaces.INewField)
    label = _("Add new field")
    id = 'add-field-form'

    # This is a trick: we want autoform to handle the additionalSchemata,
    # but want to provide our own base schema below in updateFields.
    schema = Interface

    @lazy_property
    def _schema(self):
        return interfaces.INewField

    @lazy_property
    def additionalSchemata(self):
        return [v for k, v in getAdapters((self.context, ),
            interfaces.IFieldEditorExtender)]

    def create(self, data):
        extra = {}
        factory = data.pop('factory')
        all = data.keys()

        # split regular attributes and extra ones
        for key in all:
            if key not in self._schema:
                extra[key] = data[key]
                data.pop(key)

        # create the field with regular attributes
        field_obj = factory(**data)

        # set the extra attributes using the proper adapter
        for schemata in self.additionalSchemata:
            for key in extra:
                (interface_name, property_name) = key.split('.')
                if interface_name != schemata.__name__:
                    continue
                setattr(schemata(field_obj), property_name, extra[key])

        return field_obj

    def add(self, field):
        context = self.context
        schema = IEditableSchema(context.schema)

        # move it after the last field that is not in a fieldset
        # or at top if there is no field yet in "default" fieldset
        ordered_fields = [name for (name, f) in sortedFields(context.schema)]
        default_fields = non_fieldset_fields(context.schema)
        if len(default_fields) > 0:
            position = ordered_fields.index(default_fields[-1]) + 1
        else:
            position = 0

        try:
            schema.addField(field)
        except ValueError:
            raise WidgetActionExecutionError('__name__',
                Invalid(
                    u'Please select a field name that is not already used.'
                ))

        schema.moveField(field.__name__, position)
        notify(ObjectAddedEvent(field, context.schema))
        notify(FieldAddedEvent(context, field))
        IStatusMessage(self.request).addStatusMessage(
            _(u"Field added successfully."), type='info')

    def nextURL(self):
        return "@@add-field"
class AjaxSaveHandler(BrowserView):
    """Handle AJAX save posts.
    """
    def __call__(self):
        """Handle AJAX save post.
        """

        if not authorized(self.context, self.request):
            raise Unauthorized

        source = self.request.form.get('source')
        if source:
            # Is it valid XML?
            try:
                root = etree.fromstring(source)
            except etree.XMLSyntaxError, e:
                return json.dumps({
                    'success':
                    False,
                    'message':
                    "XMLSyntaxError: %s" % e.message.encode('utf8')
                })

            # a little more sanity checking, look at first two element levels
            if root.tag != NAMESPACE + 'model':
                return json.dumps({
                    'success':
                    False,
                    'message':
                    _(u"Error: root tag must be 'model'")
                })
            for element in root.getchildren():
                if element.tag != NAMESPACE + 'schema':
                    return json.dumps({
                        'success':
                        False,
                        'message':
                        _(u"Error: all model elements must be 'schema'")
                    })

            # can supermodel parse it?
            # This is mainly good for catching bad dotted names.
            try:
                plone.supermodel.loadString(source, policy=u"dexterity")
            except SupermodelParseError, e:
                message = e.args[0].replace('\n  File "<unknown>"', '')
                return json.dumps({
                    'success':
                    False,
                    'message':
                    u"SuperModelParseError: %s" % message
                })

            # clean up formatting sins
            source = etree.tostring(root,
                                    pretty_print=True,
                                    xml_declaration=True,
                                    encoding='utf8')
            # and save to FTI
            fti = self.context.fti
            fti.manage_changeProperties(model_source=source)

            self.request.response.setHeader('Content-Type', 'application/json')
            return json.dumps({'success': True, 'message': _(u"Saved")})
Ejemplo n.º 33
0
        field_factories = [(id, factory) for id, factory in field_factories
                           if id in context.allowedFields]
    terms = []
    for (field_id, factory) in field_factories:
        terms.append(
            SimpleVocabulary.createTerm(
                factory, factory.title,
                translate(factory.title, context=request)))
    terms = sorted(terms, key=operator.attrgetter('title'))
    return SimpleVocabulary(terms)


# TextLineFactory is the default. We need to set that here to avoid a
# circular import.
TextLineFactory = FieldFactory(
    schema.TextLine, _(u'label_textline_field', default=u'Text line (String)'))
interfaces.INewField['factory'].__dict__['default'] = TextLineFactory

TextFactory = FieldFactory(schema.Text, _(u'label_text_field',
                                          default=u'Text'))
IntFactory = FieldFactory(schema.Int,
                          _(u'label_integer_field', default=u'Integer'))
FloatFactory = FieldFactory(
    schema.Float, _(u'label_float_field', default=u'Floating-point number'))
BoolFactory = FieldFactory(schema.Bool,
                           _(u'label_boolean_field', default=u'Yes/No'))
PasswordFactory = FieldFactory(schema.Password,
                               _(u'label_password_field', default=u'Password'))
DatetimeFactory = FieldFactory(
    schema.Datetime, _(u'label_datetime_field', default=u'Date/Time'))
DateFactory = FieldFactory(schema.Date, _(u'label_date_field',
Ejemplo n.º 34
0
            try:
                changes2 = self.applyChanges({"default": default})
            except schema.ValidationError, e:
                raise WidgetActionExecutionError("default", e)
            else:
                changes = changes or changes2

        if changes:
            self.status = self.successMessage
        else:
            self.status = self.noChangesMessage

        notify(SchemaModifiedEvent(self.context.aq_parent))
        self.redirectToParent()

    @button.buttonAndHandler(_(u"Cancel"), name="cancel")
    def handleCancel(self, action):
        self.redirectToParent()

    def redirectToParent(self):
        self.request.response.redirect(aq_parent(aq_inner(self.context)).absolute_url())


# form wrapper to use Plone form template
class EditView(layout.FormWrapper):
    form = FieldEditForm

    def __init__(self, context, request):
        super(EditView, self).__init__(context, request)
        self.field = context.field
Ejemplo n.º 35
0
        kwargs = copy.deepcopy(self.kw)
        kwargs.update(**kw)
        return self.fieldcls(*(self.args+args), **kwargs)


def FieldsVocabularyFactory(context):
    field_factories = getUtilitiesFor(IFieldFactory)
    terms = []
    for (field_id, factory) in field_factories:
        terms.append(SimpleVocabulary.createTerm(factory, translate(factory.title), factory.title))

    return SimpleVocabulary(terms)


# TextLineFactory is the default. We need to set that here to avoid a circular import.
TextLineFactory = FieldFactory(schema.TextLine, _(u'label_textline_field', default=u'Text line (String)'))
interfaces.INewField['factory'].__dict__['default'] = TextLineFactory

TextFactory = FieldFactory(schema.Text, _(u'label_text_field', default=u'Text'))
IntFactory = FieldFactory(schema.Int, _(u'label_integer_field', default=u'Integer'))
FloatFactory = FieldFactory(schema.Float, _(u'label_float_field', default=u'Floating-point number'))
BoolFactory = FieldFactory(schema.Bool, _(u'label_boolean_field', default=u'Yes/No'))
PasswordFactory = FieldFactory(schema.Password, _(u'label_password_field', default=u'Password'))
DatetimeFactory = FieldFactory(schema.Datetime, _(u'label_datetime_field', default=u'Date/Time'))
DateFactory = FieldFactory(schema.Date, _(u'label_date_field', default=u'Date'))


@interface.implementer(interfaces.IFieldEditFormSchema)
@component.adapter(schema_ifaces.IChoice)
def getChoiceFieldSchema(field):
    return se_schema.ITextLineChoice
Ejemplo n.º 36
0
        """ test whether a given instance of a field is editable """
        return True


def FieldsVocabularyFactory(context):
    field_factories = getUtilitiesFor(IFieldFactory)
    terms = []
    for (field_id, factory) in field_factories:
        terms.append(SimpleVocabulary.createTerm(factory, translate(factory.title), factory.title))

    return SimpleVocabulary(terms)


# TextLineFactory is the default. We need to set that here to avoid a
# circular import.
TextLineFactory = FieldFactory(schema.TextLine, _(u"label_textline_field", default=u"Text line (String)"))
interfaces.INewField["factory"].__dict__["default"] = TextLineFactory

TextFactory = FieldFactory(schema.Text, _(u"label_text_field", default=u"Text"))
IntFactory = FieldFactory(schema.Int, _(u"label_integer_field", default=u"Integer"))
FloatFactory = FieldFactory(schema.Float, _(u"label_float_field", default=u"Floating-point number"))
BoolFactory = FieldFactory(schema.Bool, _(u"label_boolean_field", default=u"Yes/No"))
PasswordFactory = FieldFactory(schema.Password, _(u"label_password_field", default=u"Password"))
DatetimeFactory = FieldFactory(schema.Datetime, _(u"label_datetime_field", default=u"Date/Time"))
DateFactory = FieldFactory(schema.Date, _(u"label_date_field", default=u"Date"))


@interface.implementer(interfaces.IFieldEditFormSchema)
@component.adapter(schema_ifaces.IChoice)
def getChoiceFieldSchema(field):
    return se_schema.ITextLineChoice
Ejemplo n.º 37
0
class SchemaListing(AutoExtensibleForm, form.Form):
    implements(IEditForm)

    ignoreContext = True
    ignoreRequest = True
    showEmptyGroups = True
    template = ViewPageTemplateFile('schema_listing.pt')

    @property
    def schema(self):
        return self.context.schema

    @property
    def additionalSchemata(self):
        return self.context.additionalSchemata

    def _iterateOverWidgets(self):
        for widget in self.widgets.values():
            yield widget
        for group in self.groups:
            for widget in group.widgets.values():
                yield widget

    def render(self):
        for widget in self._iterateOverWidgets():
            # disable fields from behaviors
            if widget.field.interface is not self.context.schema:
                widget.disabled = 'disabled'

            # limit size of the preview for text areas
            if hasattr(widget, 'rows'):
                if widget.rows is None or widget.rows > 5:
                    widget.rows = 5

        return super(SchemaListing, self).render()

    @memoize
    def _field_factory(self, field):
        field_identifier = u'%s.%s' % (field.__module__,
                                       field.__class__.__name__)
        if self.context.allowedFields is not None:
            if field_identifier not in self.context.allowedFields:
                return None
        return queryUtility(IFieldFactory, name=field_identifier)

    def field_type(self, field):
        field_factory = self._field_factory(field)
        if field_factory is not None:
            return field_factory.title
        else:
            return field.__class__.__name__

    def edit_url(self, field):
        field_factory = self._field_factory(field)
        if field_factory is not None and field_factory.editable(field):
            return '%s/%s' % (self.context.absolute_url(), field.__name__)

    def delete_url(self, field):
        return '%s/%s/@@delete' % (self.context.absolute_url(), field.__name__)

    @button.buttonAndHandler(_(u'Save Defaults'))
    def handleSaveDefaults(self, action):
        # ignore fields from behaviors by setting their widgets' modes
        # to the display mode while we extract the form values (hack!)
        widget_modes = {}
        for widget in self._iterateOverWidgets():
            if widget.field.interface is not self.context.schema:
                widget_modes[widget] = widget.mode
                widget.mode = DISPLAY_MODE

        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        for fname, value in data.items():
            self.context.schema[fname].default = value
        notify(SchemaModifiedEvent(self.context))

        # restore the actual widget modes so they render a preview
        for widget, mode in widget_modes.items():
            widget.mode = mode

        # update widgets to take the new defaults into account
        self.updateWidgets()
Ejemplo n.º 38
0
 def label(self):
     return _(u"Edit Field '${fieldname}'",
              mapping={'fieldname': self.field.__name__})
Ejemplo n.º 39
0
class FieldEditForm(AutoExtensibleForm, form.EditForm):
    implements(IFieldEditForm)
    id = 'edit-field-form'

    def __init__(self, context, request):
        super(form.EditForm, self).__init__(context, request)
        self.field = FieldProxy(context.field)

    def getContent(self):
        return self.field

    # This is a trick: we want autoform to handle the additionalSchemata,
    # but want to provide our own base schema below in updateFields.
    schema = Interface

    @lazy_property
    def _schema(self):
        return interfaces.IFieldEditFormSchema(self.field)

    @lazy_property
    def additionalSchemata(self):
        schema_context = self.context.aq_parent
        return [v for k, v in getAdapters((schema_context, self.field),
                                          interfaces.IFieldEditorExtender)]

    @lazy_property
    def label(self):
        return _(u"Edit Field '${fieldname}'",
                 mapping={'fieldname': self.field.__name__})

    def updateFields(self):
        # use a custom 'title' field to make sure it is required
        fields = field.Fields(IFieldTitle)

        # omit the order attribute since it's managed elsewhere
        fields += field.Fields(self._schema).omit(
            'order', 'title', 'default', 'missing_value', 'readonly')
        self.fields = fields

        self.updateFieldsFromSchemata()

    @button.buttonAndHandler(_(u'Save'), name='save')
    def handleSave(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        # clear current min/max to avoid range errors
        if 'min' in data:
            self.field.min = None
        if 'max' in data:
            self.field.max = None

        changes = self.applyChanges(data)

        if changes:
            IStatusMessage(self.request).addStatusMessage(
                self.successMessage, type='info')
        else:
            IStatusMessage(self.request).addStatusMessage(
                self.noChangesMessage, type='info')

        notify(SchemaModifiedEvent(self.context.aq_parent))

    @button.buttonAndHandler(_(u'Cancel'), name='cancel')
    def handleCancel(self, action):
        self.redirectToParent()

    def redirectToParent(self):
        parent = aq_parent(aq_inner(self.context))
        url = parent.absolute_url()
        if hasattr(parent, 'schemaEditorView') and parent.schemaEditorView:
            url += '/@@' + parent.schemaEditorView

        self.request.response.redirect(url)
Ejemplo n.º 40
0
class SchemaListing(AutoExtensibleForm, form.Form):

    ignoreContext = True
    ignoreRequest = True
    showEmptyGroups = True
    template = ViewPageTemplateFile('schema_listing.pt')
    ignoreRequiredOnExtract = True

    @property
    def schema(self):
        return self.context.schema

    @property
    def additionalSchemata(self):
        return self.context.additionalSchemata

    def _iterateOverWidgets(self):
        for widget in self.widgets.values():
            yield widget
        for group in self.groups:
            for widget in group.widgets.values():
                yield widget

    def render(self):
        for widget in self._iterateOverWidgets():
            # disable fields from behaviors
            if widget.field.interface is not self.context.schema:
                widget.disabled = 'disabled'

            # limit size of the preview for text areas
            if hasattr(widget, 'rows'):
                if widget.rows is None or widget.rows > 5:
                    widget.rows = 5

        return super(SchemaListing, self).render()

    @memoize
    def _field_factory(self, field):
        field_identifier = u'{0}.{1}'.format(
            field.__module__,
            field.__class__.__name__,
        )
        if self.context.allowedFields is not None:
            if field_identifier not in self.context.allowedFields:
                return None
        return queryUtility(IFieldFactory, name=field_identifier)

    def field_type(self, field):
        field_factory = self._field_factory(field)
        if field_factory is not None:
            return field_factory.title
        else:
            return field.__class__.__name__

    def protected_field(self, field):
        field_identifier = u'{0}.{1}'.format(
            field.__module__,
            field.__class__.__name__,
        )
        field_factory = queryUtility(IFieldFactory, name=field_identifier)
        return field_factory and field_factory.protected(field)

    def edit_url(self, field):
        field_factory = self._field_factory(field)
        if field_factory is not None and field_factory.editable(field):
            return '{0}/{1}'.format(
                self.context.absolute_url(),
                field.__name__,
            )

    def delete_url(self, field):

        if field.__name__ in self.context.fieldsWhichCannotBeDeleted:
            return
        url = '{0}/{1}/@@delete'.format(
            self.context.absolute_url(),
            field.__name__,
        )
        if addTokenToUrl:
            url = addTokenToUrl(url, self.request)
        return url

    @button.buttonAndHandler(
        _(u'Save Defaults'),
        condition=lambda form: getattr(form.context, 'showSaveDefaults', True))
    def handleSaveDefaults(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        for widget in self._iterateOverWidgets():
            widget_name = widget.field.getName()
            if (widget.field.interface is self.context.schema
                    and widget_name in data):
                self.context.schema[widget_name].default = data[widget_name]
        notify(SchemaModifiedEvent(self.context))

        # update widgets to take the new defaults into account
        self.updateWidgets()