provide common.NameChooser and use it on browser.form
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1601 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
fe8d2792d3
commit
f43676c843
5 changed files with 59 additions and 48 deletions
15
README.txt
15
README.txt
|
@ -602,7 +602,8 @@ that are shown in the end-user interface.
|
|||
Creating an object
|
||||
------------------
|
||||
|
||||
>>> from loops.browser.form import CreateObjectForm, CreateObject, ResourceNameChooser
|
||||
>>> from loops.common import NameChooser
|
||||
>>> from loops.browser.form import CreateObjectForm, CreateObject
|
||||
>>> form = CreateObjectForm(m112, TestRequest())
|
||||
|
||||
>>> from loops.interfaces import INote, ITypeConcept
|
||||
|
@ -614,7 +615,7 @@ Creating an object
|
|||
>>> note_tc.conceptType = typeObject
|
||||
>>> ITypeConcept(note_tc).typeInterface = INote
|
||||
|
||||
>>> component.provideAdapter(ResourceNameChooser)
|
||||
>>> component.provideAdapter(NameChooser)
|
||||
>>> request = TestRequest(form={'form.title': u'Test Note',
|
||||
... 'form.type': u'.loops/concepts/note'})
|
||||
>>> view = NodeView(m112, request)
|
||||
|
@ -646,16 +647,16 @@ created object:
|
|||
>>> sorted(t.__name__ for t in note.getConcepts())
|
||||
[u'note', u'topic']
|
||||
|
||||
When creating an object its name is automatically generated using the title
|
||||
When creating an object its name may be automatically generated using the title
|
||||
of the object. Let's make sure that the name chooser also handles special
|
||||
and possibly critcal cases:
|
||||
|
||||
>>> nc = ResourceNameChooser(resources)
|
||||
>>> nc.chooseName(u'abc: (cde)', None)
|
||||
>>> nc = NameChooser(resources)
|
||||
>>> nc.chooseName(u'', Resource(u'abc: (cde)'))
|
||||
u'abc_cde'
|
||||
>>> nc.chooseName(u'\xdcml\xe4ut', None)
|
||||
>>> nc.chooseName(u'', Resource(u'\xdcml\xe4ut'))
|
||||
u'uemlaeut'
|
||||
>>> nc.chooseName(u'A very very loooooong title', None)
|
||||
>>> nc.chooseName(u'', Resource(u'A very very loooooong title'))
|
||||
u'a_title'
|
||||
|
||||
Editing an Object
|
||||
|
|
|
@ -612,8 +612,6 @@
|
|||
permission="zope.Public"
|
||||
/>
|
||||
|
||||
<zope:adapter factory="loops.browser.form.ResourceNameChooser" />
|
||||
|
||||
<!-- inner HTML views -->
|
||||
|
||||
<page
|
||||
|
|
|
@ -198,7 +198,6 @@ class EditObject(FormController):
|
|||
return self.view.loopsRoot
|
||||
|
||||
def updateFields(self, obj):
|
||||
# TODO: replace with `applyChanges()`
|
||||
form = self.request.form
|
||||
ti = IType(obj).typeInterface
|
||||
if ti is not None:
|
||||
|
@ -218,6 +217,7 @@ class EditObject(FormController):
|
|||
filename = getattr(value, 'filename', '')
|
||||
value = value.read()
|
||||
if filename:
|
||||
#self.request.form['filename'] = filename
|
||||
contentType = guess_content_type(filename, value[:100])
|
||||
if contentType:
|
||||
self.request.form['form.contentType'] = contentType[0]
|
||||
|
@ -256,12 +256,17 @@ class CreateObject(EditObject):
|
|||
|
||||
def update(self):
|
||||
form = self.request.form
|
||||
obj = Resource()
|
||||
container = self.loopsRoot.getResourceManager()
|
||||
title = form.get('form.title')
|
||||
if not title:
|
||||
raise BadRequest('Title field is empty')
|
||||
name = INameChooser(container).chooseName(title, obj)
|
||||
obj = Resource(title)
|
||||
data = form.get('form.data')
|
||||
if data and isinstance(data, FileUpload):
|
||||
name = getattr(data, 'filename', None)
|
||||
else:
|
||||
name = None
|
||||
name = INameChooser(container).chooseName(name, obj)
|
||||
container[name] = obj
|
||||
tc = form.get('form.type') or '.loops/concepts/note'
|
||||
obj.resourceType = self.loopsRoot.loopsTraverse(tc)
|
||||
|
@ -269,37 +274,3 @@ class CreateObject(EditObject):
|
|||
self.updateFields(obj)
|
||||
return True
|
||||
|
||||
|
||||
specialCharacters = {
|
||||
'\xc4': 'Ae', '\xe4': 'ae', '\xd6': 'Oe', '\xf6': 'oe',
|
||||
'\xdc': 'Ue', '\xfc': 'ue', '\xdf': 'ss'}
|
||||
|
||||
class ResourceNameChooser(NameChooser):
|
||||
|
||||
adapts(IResourceManager)
|
||||
|
||||
def chooseName(self, title, obj):
|
||||
result = []
|
||||
if len(title) > 15:
|
||||
words = title.split()
|
||||
if len(words) > 1:
|
||||
title = '_'.join((words[0], words[-1]))
|
||||
for c in title:
|
||||
try:
|
||||
c = c.encode('ISO8859-15')
|
||||
except UnicodeEncodeError:
|
||||
continue
|
||||
if c in specialCharacters:
|
||||
result.append(specialCharacters[c].lower())
|
||||
continue
|
||||
if ord(c) > 127:
|
||||
c = chr(ord(c) & 127)
|
||||
if c in ('_., '):
|
||||
result.append('_')
|
||||
elif not c.isalpha() and not c.isdigit():
|
||||
continue
|
||||
else:
|
||||
result.append(c.lower())
|
||||
name = unicode(''.join(result))
|
||||
return super(ResourceNameChooser, self).chooseName(name, obj)
|
||||
|
||||
|
|
43
common.py
43
common.py
|
@ -22,14 +22,14 @@ Common stuff.
|
|||
$Id$
|
||||
"""
|
||||
|
||||
from zope.app import zapi
|
||||
from zope.app.container.contained import NameChooser as BaseNameChooser
|
||||
from zope.dublincore.interfaces import IZopeDublinCore
|
||||
from zope.dublincore.annotatableadapter import ZDCAnnotatableAdapter
|
||||
from zope.dublincore.zopedublincore import ScalarProperty
|
||||
from zope.component import adapts
|
||||
from zope.interface import implements
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from loops.interfaces import ILoopsObject, IConcept, IResource
|
||||
from loops.interfaces import ILoopsObject, ILoopsContained, IConcept, IResource
|
||||
from loops.interfaces import IResourceAdapter
|
||||
|
||||
|
||||
|
@ -93,3 +93,42 @@ class LoopsDCAdapter(ZDCAnnotatableAdapter):
|
|||
title = property(Title, setTitle)
|
||||
|
||||
|
||||
class NameChooser(BaseNameChooser):
|
||||
|
||||
adapts(ILoopsContained)
|
||||
|
||||
def chooseName(self, name, obj):
|
||||
if not name:
|
||||
name = self.generateName(obj)
|
||||
name = super(NameChooser, self).chooseName(name, obj)
|
||||
return name
|
||||
|
||||
def generateName(self, obj):
|
||||
title = obj.title
|
||||
result = []
|
||||
if len(title) > 15:
|
||||
words = title.split()
|
||||
if len(words) > 1:
|
||||
title = '_'.join((words[0], words[-1]))
|
||||
for c in title:
|
||||
try:
|
||||
c = c.encode('ISO8859-15')
|
||||
except UnicodeEncodeError:
|
||||
continue
|
||||
if c in self.specialCharacters:
|
||||
result.append(self.specialCharacters[c].lower())
|
||||
continue
|
||||
if ord(c) > 127:
|
||||
c = chr(ord(c) & 127)
|
||||
if c in ('_., '):
|
||||
result.append('_')
|
||||
elif not c.isalpha() and not c.isdigit():
|
||||
continue
|
||||
else:
|
||||
result.append(c.lower())
|
||||
name = unicode(''.join(result))
|
||||
return name
|
||||
|
||||
specialCharacters = {
|
||||
'\xc4': 'Ae', '\xe4': 'ae', '\xd6': 'Oe', '\xf6': 'oe',
|
||||
'\xdc': 'Ue', '\xfc': 'ue', '\xdf': 'ss'}
|
||||
|
|
|
@ -289,6 +289,8 @@
|
|||
<adapter factory="loops.resource.DocumentReadFileAdapter" />
|
||||
<adapter factory="loops.resource.DocumentWriteFileAdapter" />
|
||||
|
||||
<adapter factory="loops.common.NameChooser" />
|
||||
|
||||
<adapter factory="loops.type.LoopsType" />
|
||||
<adapter factory="loops.type.ConceptType" />
|
||||
<adapter factory="loops.type.ResourceType"
|
||||
|
|
Loading…
Add table
Reference in a new issue