From: David G. <svn...@pl...> - 2011-12-31 21:29:35
|
Repository: plone.schemaeditor Branch: refs/heads/master Date: 2011-12-31T13:29:15-08:00 Author: David Glick (davisagli) <dg...@gm...> Commit: https://github.com/plone/plone.schemaeditor/commit/7512298bbfcd9bdfc345ed834dd829b3d9f783f5 add more checks for reserved field names Files changed: M CHANGES.txt M plone/schemaeditor/interfaces.py M plone/schemaeditor/tests/editing.txt diff --git a/CHANGES.txt b/CHANGES.txt index 2fc81b4..7719edd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,11 @@ Changelog 1.2.0 - unreleased ------------------ +* Prevent the user from creating fields with names that are reserved for + Dublin Core metadata. ``title`` and ``description`` can still be used + as long as the fields are of the correct type. + [davisagli] + * Remove unhelpful help text for min_length and max_length fields. [davisagli] diff --git a/plone/schemaeditor/interfaces.py b/plone/schemaeditor/interfaces.py index cda3da9..40d732d 100644 --- a/plone/schemaeditor/interfaces.py +++ b/plone/schemaeditor/interfaces.py @@ -1,9 +1,9 @@ import re from zope.component.interfaces import IObjectEvent +from zope.interface import Invalid, invariant from zope.interface.interfaces import Interface, IInterface, Attribute from zope.publisher.interfaces.browser import IBrowserPage from zope.schema import Object, TextLine, Text, Choice, ASCIILine -from zope.schema import ValidationError from zope.schema.interfaces import IField from z3c.form.interfaces import IEditForm from OFS.interfaces import IItem @@ -65,17 +65,20 @@ class IFieldEditFormSchema(Interface): """ The schema describing the form fields for a field. """ - -class InvalidIdError(ValidationError): - __doc__ = _(u'Please use only letters, numbers and the following characters: _.') +RESERVED_NAMES = ( + "subject", "format", "language", "creators", "contributors", "rights", + "effective_date", "expiration_date" + ) # a letter followed by letters, numbers, or underscore ID_RE = re.compile(r'^[a-z][\w\d\.]*$') -def isValidFieldId(value): - if ID_RE.match(value): - return True - raise InvalidIdError +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 class INewField(Interface): @@ -89,7 +92,7 @@ class INewField(Interface): title=_(u'Short Name'), description=_(u'Used for programmatic access to the field.'), required=True, - constraint=isValidFieldId, + constraint=isValidFieldName, ) description = Text( @@ -106,3 +109,11 @@ class INewField(Interface): # 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.')) diff --git a/plone/schemaeditor/tests/editing.txt b/plone/schemaeditor/tests/editing.txt index 7e31cff..e171096 100644 --- a/plone/schemaeditor/tests/editing.txt +++ b/plone/schemaeditor/tests/editing.txt @@ -246,3 +246,39 @@ and saved. [event: SchemaModifiedEvent on DummySchemaContext] [event: ObjectModifiedEvent on List] [event: SchemaModifiedEvent on DummySchemaContext] + +Reserved field names +-------------------- + +Since fields are accessible by names as attributes of a content item, we +reserve some field names that are already in use by Dublin Core metadata +attributes. Users cannot add fields with these names. + + >>> for fname in ("subject", "format", "language", + ... "creators", "contributors", "rights", + ... "effective_date", "expiration_date"): + ... browser.open(portal_url + '/@@schemaeditor') + ... browser.getControl('Add new field').click() + ... browser.getControl('Title').value = fname + ... browser.getControl('Short Name').value = fname + ... browser.getControl('Add').click() + ... assert 'is a reserved field name' in browser.contents + +The ``title`` and ``description`` field names are also reserved, but since +it's a common need to customize the wording of the label and help text for +these fields, they are allowed as long as the field is of the correct type. + + >>> browser.open(portal_url + '/@@schemaeditor') + >>> browser.getControl('Add new field').click() + >>> browser.getControl('Title').value = 'title' + >>> browser.getControl('Short Name').value = 'title' + >>> browser.getControl('Field type').getControl('Integer').selected = True + >>> browser.getControl('Add').click() + >>> browser.url + 'http://nohost/@@schemaeditor/@@add-field' + >>> browser.getControl('Field type').getControl('String').selected = True + >>> browser.getControl('Add').click() + [event: ObjectAddedEvent on TextLine] + [event: SchemaModifiedEvent on DummySchemaContext] + >>> browser.url + 'http://nohost/@@schemaeditor' |