[Checkins] SVN: Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder. Initial work on formlib-based contents view.
Charlie Clark
charlie at begeistert.org
Sun Oct 5 11:55:38 EDT 2008
Log message for revision 91782:
Initial work on formlib-based contents view.
Changed:
A Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.py
A Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.txt
-=-
Added: Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.py
===================================================================
--- Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.py (rev 0)
+++ Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.py 2008-10-05 15:55:38 UTC (rev 91782)
@@ -0,0 +1,266 @@
+from zope.interface import Interface
+from zope.schema import Bool, TextLine
+from zope import schema
+from zope.formlib import form
+
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
+from Products.CMFDefault.browser.utils import ViewBase
+from Products.CMFDefault.formlib.form import ContentEditFormBase
+from Products.CMFDefault.utils import Message as _
+
+class IFolderItem(Interface):
+ """Interface for folderish objects contents."""
+
+ select = Bool(
+ required=False)
+
+ name = TextLine(
+ title=u"Name",
+ required=False,
+ readonly=True)
+
+class ContentsView(ContentEditFormBase):
+ """Folder contents view for camaoCmsMasterPages"""
+
+ actions = form.Actions(
+ form.Action(
+ name='rename',
+ label=_(u'Rename'),
+ validator='check_items',
+ success='handle_rename'),
+ form.Action(
+ name='cut',
+ label=_(u'Cut'),
+ validator='check_items',
+ success='handle_cut'),
+ form.Action(
+ name='copy',
+ label=_(u'Copy'),
+ validator='check_items',
+ success='handle_copy'),
+ form.Action(
+ name='paste',
+ label=_(u'Paste'),
+ condition='check_clipboard_data',
+ success='handle_paste'),
+ form.Action(
+ name='delete',
+ label=_(u'Delete'),
+ validator='check_items',
+ success='handle_delete'),
+ form.Action(
+ name='up',
+ label=_(u'Up'),
+ validator='check_items',
+ success='handle_up'),
+ form.Action(
+ name='down',
+ label=_(u'Down'),
+ validator='check_items',
+ success='handle_down'),
+ form.Action(
+ name='top',
+ label=_(u'Top'),
+ validator='check_items',
+ success='handle_top'),
+ form.Action(
+ name='bottom',
+ label=_(u'Bottom'),
+ validator='check_items',
+ success='handle_bottom')
+ )
+
+ template = ViewPageTemplateFile('templates/contents.pt')
+
+ errors = ()
+
+
+ def __init__(self, *args, **kw):
+ super(ContentsView, self).__init__(*args, **kw)
+ self.form_fields = form.FormFields()
+ self.contents = self.context.contentValues()
+
+ for item in self.contents:
+ for n, f in schema.getFieldsInOrder(IFolderItem):
+ field = form.FormField(f, n, item.id)
+ self.form_fields += form.FormFields(field)
+
+ def is_orderable(self):
+ """Returns true if folder contents may be reordered"""
+ pass
+
+ def is_sortable(self):
+ """Returns true if the folder contents view may be sorted for display"""
+ pass
+
+ def setUpWidgets(self, ignore_request=False):
+ data = {}
+ for i in self.contents:
+ data['%s.name' %i.id] = i.id
+ self.widgets = form.setUpDataWidgets(
+ self.form_fields, self.prefix, self.context,
+ self.request, data=data, ignore_request=ignore_request)
+
+ def layout_fields(self):
+ """Return the widgets for the form in the interface field order"""
+ fields = []
+
+ for index, item in enumerate(self.contents):
+ field = {'ModificationDate':item.ModificationDate()}
+ field['select'] = self.widgets['%s.select' % item.getId()]
+ field['name'] = self.widgets['%s.name' % item.getId()]
+ field['url'] = item.absolute_url()
+ field['title'] = item.TitleOrId()
+ field['icon'] = item.icon
+ field['position'] = index + 1
+ fields.append(field.copy())
+ return fields
+
+ def _get_ids(self, data):
+ """Strip prefixes from ids that have been selected"""
+ ids = [k.split(".")[0] for k, v in data.items() if v == True]
+ return ids
+
+ def check_items(self, action, data):
+ """Check whether any items have been selected for the requested action."""
+ errors = form.getWidgetsData(self.widgets, 'form', data)
+ if len(self._get_ids(data)) == 0:
+ return [_(u"Please select one or more items first.")]
+
+ def check_clipboard_data(self, action):
+ return bool(self.context.cb_dataValid())
+
+ def handle_new(self, action, data):
+ return self._setRedirect('portal_types', 'object/new')
+
+ def handle_rename(self, action, data):
+ ids = self._get_ids(data)
+ new_ids = [str(data['%s.name' % k]) for k in ids]
+ self.status = _(u'Item renamed.')
+ self.context.manage_renameObjects(ids, new_ids)
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_cut(self, action, data):
+ ids = self._get_ids(data)
+
+ try:
+ self.context.manage_cutObjects(ids, self.request)
+ if len(ids) == 1:
+ self.status = _(u'Item cut.')
+ else:
+ self.status = _(u'Items cut.')
+ except CopyError:
+ self.status = _(u'CopyError: Cut failed.')
+ except zExceptions_Unauthorized:
+ self.status = _(u'Unauthorized: Cut failed.')
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_copy(self, action, data):
+ ids = self._get_ids(data)
+
+ try:
+ self.context.manage_copyObjects(ids, self.request)
+ if len(ids) == 1:
+ self.status = _(u'Item copied.')
+ else:
+ self.status = _(u'Items copied.')
+ except CopyError:
+ self.status = _(u'CopyError: Copy failed.')
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_paste(self, action, data):
+ try:
+ result = self.context.manage_pasteObjects(self.request['__cp'])
+ if len(result) == 1:
+ self.status = _(u'Item pasted.')
+ else:
+ self.status = _(u'Items pasted.')
+ except CopyError, error:
+ self.status = _(u'CopyError: Paste failed.')
+ self.request['RESPONSE'].expireCookie('__cp',
+ path='%s' % (self.request['BASEPATH1'] or "/"))
+
+ except zExceptions_Unauthorized:
+ self.status = _(u'Unauthorized: Paste failed.')
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_delete(self, action, data):
+ ids = self._get_ids(data)
+ self.context.manage_delObjects(list(ids))
+ if len(ids) == 1:
+ self.status = _(u'Item deleted.')
+ else:
+ self.status = _(u'Items deleted.')
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_up(self, action, data):
+ ids = self._get_ids(data)
+ delta = self.request.form.get('delta', 1)
+ subset_ids = [ obj.getId()
+ for obj in self.context.listFolderContents() ]
+ try:
+ attempt = self.context.moveObjectsUp(ids, delta,
+ subset_ids=subset_ids)
+ if attempt == 1:
+ self.status = _(u'Item moved up.')
+ elif attempt > 1:
+ self.status = _(u'Items moved up.')
+ else:
+ self.status = _(u'Nothing to change.')
+ except ValueError:
+ self.status = _(u'ValueError: Move failed.')
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_down(self, action, data):
+ ids = self._get_ids(data)
+ delta = self.request.form.get('delta', 1)
+ subset_ids = [ obj.getId()
+ for obj in self.context.listFolderContents() ]
+ try:
+ attempt = self.context.moveObjectsDown(ids, delta,
+ subset_ids=subset_ids)
+ if attempt == 1:
+ self.status = _(u'Item moved down.')
+ elif attempt > 1:
+ self.status = _(u'Items moved down.')
+ else:
+ self.status = _(u'Nothing to change.')
+ except ValueError:
+ self.status = _(u'ValueError: Move failed.')
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_top(self, action, data):
+ ids = self._get_ids(data)
+ subset_ids = [ obj.getId()
+ for obj in self.context.listFolderContents() ]
+ try:
+ attempt = self.context.moveObjectsToTop(ids,
+ subset_ids=subset_ids)
+ if attempt == 1:
+ self.status = _(u'Item moved to top.')
+ elif attempt > 1:
+ self.status = _(u'Items moved to top.')
+ else:
+ self.status = _(u'Nothing to change.')
+ except ValueError:
+ self.status = _(u'ValueError: Move failed.')
+ return self._setRedirect('portal_types', 'object/contents')
+
+ def handle_bottom(self, action, data):
+ ids = self._get_ids(data)
+ subset_ids = [ obj.getId()
+ for obj in self.context.listFolderContents() ]
+ try:
+ attempt = self.context.moveObjectsToBottom(ids,
+ subset_ids=subset_ids)
+ if attempt == 1:
+ self.status = _(u'Item moved to bottom.')
+ elif attempt > 1:
+ self.status = _(u'Items moved to bottom.')
+ else:
+ self.status = _(u'Nothing to change.')
+ except ValueError:
+ self.status = _(u'ValueError: Move failed.')
+ return self._setRedirect('portal_types', 'object/contents')
+
Added: Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.txt
===================================================================
--- Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.txt (rev 0)
+++ Products.CMFDefault/branches/Charlie_X/Products/CMFDefault/browser/new_folder.txt 2008-10-05 15:55:38 UTC (rev 91782)
@@ -0,0 +1,86 @@
+Browser Views for IFolderish
+
+
+ The required environment:
+
+ Setting up a dummy site with required tools::
+
+ >>> from Products.CMFCore.tests.base.dummy import DummySite
+ >>> site = DummySite('site')
+
+ >>> from Products.CMFCore.tests.base.dummy import DummyTool
+ >>> from zope.component import getSiteManager
+ >>> from Products.CMFCore.interfaces import IPropertiesTool
+ >>> sm = getSiteManager()
+ >>> mtool = site._setObject('portal_membership', DummyTool())
+ >>> ptool = site._setObject('portal_properties', DummyTool())
+ >>> sm.registerUtility(ptool, IPropertiesTool)
+ >>> ttool = site._setObject('portal_types', DummyTool())
+ >>> utool = site._setObject('portal_url', DummyTool())
+
+
+ Basic functionality without security setup:
+
+ Setting up a simple request and an empty context object::
+
+ >>> class DummyRequest(dict):
+ ... def __init__(self):
+ ... self['ACTUAL_URL'] = 'actual_url'
+ ... self.form = {}
+ >>> request = DummyRequest()
+
+ >>> from Products.CMFCore.PortalFolder import PortalFolder
+ >>> context = PortalFolder('foo').__of__(site)
+
+ The FolderView interface used by templates::
+
+ >>> from Products.CMFDefault.browser.folder import FolderView
+ >>> view = FolderView(context, request)
+
+ >>> view.title()
+ u''
+
+ >>> view.description()
+ u''
+
+ >>> view.has_local()
+ False
+
+ The FolderContentsView interface used by templates::
+
+ >>> from Products.CMFDefault.browser.new_folder import ContentsView
+ >>> view = ContentsView(context, request)
+
+ >>> view.title()
+ u''
+
+ >>> view.description()
+ u''
+
+ >>> view.up_info()
+ {'url': u'', 'id': u'Root', 'icon': u''}
+
+
+ >>> view.layout_fields()
+ []
+
+ >>> view.is_orderable()
+ False
+
+ >>> view.is_sortable()
+ False
+
+ The FolderContentsView checkers used by button actions::
+
+ >>> view.check_clipboard_data()
+ False
+
+ >>> view.check_items()
+ False
+
+ Finally we have to clean up::
+
+ >>> from zope.testing.cleanup import cleanUp
+ >>> cleanUp()
+
+ The tests need extending with some dummy objects for sorting, deleting, etc.
\ No newline at end of file
More information about the Checkins
mailing list