[Checkins] SVN: Products.CMFDefault/trunk/Products/CMFDefault/ - added FallbackAddView
Yvo Schubbe
y.2008 at wcm-solutions.de
Wed Sep 24 07:02:33 EDT 2008
Log message for revision 91417:
- added FallbackAddView
- aligned ContentAddFormBase and FileAddView to the ++add++ namespace
Changed:
U Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt
U Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml
U Products.CMFDefault/trunk/Products/CMFDefault/browser/file.py
U Products.CMFDefault/trunk/Products/CMFDefault/browser/file.txt
U Products.CMFDefault/trunk/Products/CMFDefault/browser/folder.py
U Products.CMFDefault/trunk/Products/CMFDefault/formlib/form.py
-=-
Modified: Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt 2008-09-24 10:41:45 UTC (rev 91416)
+++ Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt 2008-09-24 11:02:32 UTC (rev 91417)
@@ -4,6 +4,9 @@
2.2.0 (unreleased)
------------------
+- views: Added FallbackAddView.
+ This add form works with any portal type. It just asks for the ID.
+
- formlib widgets: Added special input widget for object IDs.
- main_template: Display action icons, thereby replacing the separate
@@ -39,7 +42,7 @@
- Image, File: make ZMI "edit" view work.
-- views: Added ContentEditFormBase and FileAddView.
+- views: Added ContentAddFormBase and FileAddView.
This shows how form-driven content creation works. The content is created
without using the constructor methods provided by the types tool.
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml 2008-09-24 10:41:45 UTC (rev 91416)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/configure.zcml 2008-09-24 11:02:32 UTC (rev 91417)
@@ -20,6 +20,8 @@
permission="cmf.ListFolderContents"
/>
+ <adapter factory=".folder.FallbackAddView" />
+
<adapter factory=".metadata.MinimalMetadataSchemaAdapter"/>
<browser:page
@@ -105,12 +107,9 @@
<adapter factory=".file.FileSchemaAdapter"/>
- <browser:page
- for="Products.CMFCore.interfaces.IFolderish"
- layer="..interfaces.ICMFDefaultSkin"
- name="addFile.html"
- class=".file.FileAddView"
- permission="cmf.AddPortalContent"
+ <adapter
+ name="cmf.file"
+ factory=".file.FileAddView"
/>
<browser:page
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/file.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/file.py 2008-09-24 10:41:45 UTC (rev 91416)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/file.py 2008-09-24 11:02:32 UTC (rev 91417)
@@ -15,6 +15,8 @@
$Id$
"""
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass
from zope.component import adapts
from zope.formlib import form
from zope.interface import implements
@@ -29,6 +31,7 @@
from Products.CMFDefault.formlib.schema import ProxyFieldProperty
from Products.CMFDefault.formlib.schema import SchemaAdapterBase
from Products.CMFDefault.interfaces import IMutableFile
+from Products.CMFDefault.permissions import AddPortalContent
from Products.CMFDefault.utils import Message as _
@@ -90,23 +93,23 @@
"""Add view for IMutableFile.
"""
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(AddPortalContent)
+
form_fields = (
form.FormFields(IFileSchema).select('title', 'description') +
- form.FormFields(FileUpload(__name__='file', title=_(u'Upload')),
- TextLine(__name__='portal_type', default=u'File'))
+ form.FormFields(FileUpload(__name__='file', title=_(u'Upload')))
)
def setUpWidgets(self, ignore_request=False):
super(FileAddView,
self).setUpWidgets(ignore_request=ignore_request)
self.widgets['description'].height = 3
- self.widgets['portal_type'].hide = True
self.widgets['file'].displayWidth = 60
def create(self, data):
obj = super(FileAddView,
- self).create(dict(id=data['file'].filename,
- portal_type=data['portal_type']))
+ self).create(dict(id=data['file'].filename))
adapted = IFileSchema(obj)
adapted.title = data['title']
adapted.language = u''
@@ -114,7 +117,9 @@
adapted.file = data['file']
return obj
+InitializeClass(FileAddView)
+
class FileEditView(ContentEditFormBase):
"""Edit view for IMutableFile.
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/file.txt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/file.txt 2008-09-24 10:41:45 UTC (rev 91416)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/file.txt 2008-09-24 11:02:32 UTC (rev 91417)
@@ -15,7 +15,7 @@
Use the add form without input.
- >>> browser.open('http://localhost/site/@@addFile.html')
+ >>> browser.open('http://localhost/site/++add++File')
>>> '[[cmf_default][Add [[cmf_default][File]]]]' in browser.contents
True
>>> browser.getControl('[[zope][Add]]').click()
@@ -27,7 +27,7 @@
Use the add form with valid input.
>>> from StringIO import StringIO
- >>> browser.open('http://localhost/site/@@addFile.html')
+ >>> browser.open('http://localhost/site/++add++File')
>>> '[[cmf_default][Add [[cmf_default][File]]]]' in browser.contents
True
>>> browser.getControl(name='form.title').value = 'FILE TITLE'
Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/folder.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/folder.py 2008-09-24 10:41:45 UTC (rev 91416)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/folder.py 2008-09-24 11:02:32 UTC (rev 91417)
@@ -15,8 +15,12 @@
$Id$
"""
+from AccessControl import ClassSecurityInfo
from DocumentTemplate import sequence
+from Globals import InitializeClass
from Products.PythonScripts.standard import thousands_commas
+from zope.formlib import form
+from zope.schema import ASCIILine
from ZTUtils import Batch
from ZTUtils import LazyFilter
from ZTUtils import make_query
@@ -24,6 +28,8 @@
from Products.CMFCore.interfaces import IDynamicType
from Products.CMFDefault.exceptions import CopyError
from Products.CMFDefault.exceptions import zExceptions_Unauthorized
+from Products.CMFDefault.formlib.form import ContentAddFormBase
+from Products.CMFDefault.formlib.widgets import IDInputWidget
from Products.CMFDefault.permissions import AddPortalContent
from Products.CMFDefault.permissions import DeleteObjects
from Products.CMFDefault.permissions import ListFolderContents
@@ -38,6 +44,35 @@
from utils import ViewBase
+class FallbackAddView(ContentAddFormBase):
+
+ """Add view for IDynamicType content.
+ """
+
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(AddPortalContent)
+
+ form_fields = form.FormFields(ASCIILine(__name__='id', title=_(u'ID')))
+ form_fields['id'].custom_widget = IDInputWidget
+
+ def createAndAdd(self, data):
+ if not self.ti.product:
+ return super(FallbackAddView, self).createAndAdd(data)
+
+ # for portal types with oldstyle factories
+ container = self.context
+ name = container.invokeFactory(self.ti.getId(), data['id'])
+ obj = container._getOb(name)
+
+ obj_type = translate(obj.Type(), container)
+ self.status = _(u'${obj_type} added.', mapping={'obj_type': obj_type})
+ self._finished_add = True
+ self._added_obj = obj
+ return obj
+
+InitializeClass(FallbackAddView)
+
+
# XXX: This should be refactored using formlib. Please don't import from this
# module, things might be changed without further notice.
Modified: Products.CMFDefault/trunk/Products/CMFDefault/formlib/form.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/formlib/form.py 2008-09-24 10:41:45 UTC (rev 91416)
+++ Products.CMFDefault/trunk/Products/CMFDefault/formlib/form.py 2008-09-24 11:02:32 UTC (rev 91417)
@@ -23,6 +23,7 @@
from Products.Five.formlib.formbase import PageDisplayForm
from Products.Five.formlib.formbase import PageForm
from zope.app.container.interfaces import INameChooser
+from zope.component import adapts
from zope.component import getUtility
from zope.component.interfaces import IFactory
from zope.datetime import parseDatetimetz
@@ -30,11 +31,17 @@
from zope.i18n.interfaces import IUserPreferredLanguages
from zope.i18n.locales import LoadLocaleError
from zope.i18n.locales import locales
+from zope.interface import implementsOnly
+from zope.publisher.interfaces.browser import IBrowserView
from ZTUtils import make_query
+from Products.CMFCore.interfaces import IFolderish
+from Products.CMFCore.interfaces import ITypeInformation
+from Products.CMFDefault.browser.utils import ViewBase
+from Products.CMFDefault.exceptions import AccessControl_Unauthorized
+from Products.CMFDefault.interfaces import ICMFDefaultSkin
from Products.CMFDefault.utils import Message as _
from Products.CMFDefault.utils import translate
-from Products.CMFDefault.browser.utils import ViewBase
# from zope.publisher.http.HTTPRequest
@@ -105,6 +112,9 @@
class ContentAddFormBase(_EditFormMixin, PageAddForm):
+ adapts(IFolderish, ICMFDefaultSkin, ITypeInformation)
+ implementsOnly(IBrowserView)
+
actions = form.Actions(
form.Action(
name='add',
@@ -118,17 +128,23 @@
success='handle_cancel_success',
failure='handle_cancel_failure'))
- description = u''
+ def __init__(self, context, request, ti):
+ self.context = context
+ self.request = request
+ self.ti = ti
+ # BBB: for Zope 2.10
+ if getattr(self.request, 'locale', None) is None:
+ self.request.locale = _getLocale(request)
@property
def label(self):
- obj_type_id = self.widgets['portal_type']._getFormValue()
- # look it up to get an i18n message object with correct i18n domain
- ttool = self._getTool('portal_types')
- fti = ttool.getTypeInfo(obj_type_id)
- obj_type = translate(fti.Title(), self.context)
+ obj_type = translate(self.ti.Title(), self.context)
return _(u'Add ${obj_type}', mapping={'obj_type': obj_type})
+ @property
+ def description(self):
+ return self.ti.Description()
+
#same as in form.AddFormBase but without action decorator
def handle_add(self, action, data):
self.createAndAdd(data)
@@ -143,22 +159,23 @@
('object/folderContents', 'object/view'))
def create(self, data):
- id = data.pop('id', '')
- portal_type = data.pop('portal_type')
- ttool = self._getTool('portal_types')
- fti = ttool.getTypeInfo(portal_type)
- factory = getUtility(IFactory, fti.factory)
+ id = data.pop('id', '') or ''
+ factory = getUtility(IFactory, self.ti.factory)
obj = factory(id=id, **data)
- obj._setPortalTypeName(portal_type)
+ obj._setPortalTypeName(self.ti.getId())
return obj
def add(self, obj):
container = self.context
+ portal_type = self.ti.getId()
+ # check allowed (sometimes redundant, but better safe than sorry)
+ if not self.ti.isConstructionAllowed(container):
+ raise AccessControl_Unauthorized('Cannot create %s' % portal_type)
+
#check container constraints
ttool = self._getTool('portal_types')
container_ti = ttool.getTypeInfo(container)
- portal_type = obj.getPortalTypeName()
if container_ti is not None and \
not container_ti.allowType(portal_type):
raise ValueError('Disallowed subobject type: %s' % portal_type)
@@ -168,7 +185,7 @@
container._setObject(name, obj)
obj = container._getOb(name)
- obj_type = translate(obj.Type(), self.context)
+ obj_type = translate(obj.Type(), container)
self.status = _(u'${obj_type} added.', mapping={'obj_type': obj_type})
self._finished_add = True
self._added_obj = obj
@@ -176,12 +193,11 @@
def nextURL(self):
obj = self._added_obj
- fti = obj.getTypeInfo()
message = translate(self.status, self.context)
if isinstance(message, unicode):
message = message.encode(self._getBrowserCharset())
- return '%s/%s?%s' % (obj.absolute_url(), fti.immediate_view,
+ return '%s/%s?%s' % (obj.absolute_url(), self.ti.immediate_view,
make_query(portal_status_message=message))
More information about the Checkins
mailing list