[z3-checkins] r8282 - in z3/Five/trunk: . tests/products/FiveTest
regebro at codespeak.net
regebro at codespeak.net
Fri Jan 14 19:24:08 MET 2005
Author: regebro
Date: Fri Jan 14 19:24:08 2005
New Revision: 8282
Added:
z3/Five/trunk/edit.pt (props changed)
- copied unchanged from r8221, z3/Five/branch/regebro-forms_support/edit.pt
Modified:
z3/Five/trunk/CHANGES.txt
z3/Five/trunk/browser.py
z3/Five/trunk/browserconfigure.py
z3/Five/trunk/configure.zcml
z3/Five/trunk/meta.zcml
z3/Five/trunk/tests/products/FiveTest/__init__.py
z3/Five/trunk/tests/products/FiveTest/configure.zcml
z3/Five/trunk/tests/products/FiveTest/interfaces.py
z3/Five/trunk/tests/products/FiveTest/simplecontent.py
Log:
Support for browser:editform
Modified: z3/Five/trunk/CHANGES.txt
==============================================================================
--- z3/Five/trunk/CHANGES.txt (original)
+++ z3/Five/trunk/CHANGES.txt Fri Jan 14 19:24:08 2005
@@ -20,6 +20,8 @@
zope.security.checkPermission, which checks if the current user
has a permission on an object.
+* Support for browser:editform. You can now use schemas for editing.
+
Five 0.2b
---------
Modified: z3/Five/trunk/browser.py
==============================================================================
--- z3/Five/trunk/browser.py (original)
+++ z3/Five/trunk/browser.py Fri Jan 14 19:24:08 2005
@@ -16,11 +16,17 @@
from AccessControl import ClassSecurityInfo
from Globals import InitializeClass
from interfaces import ITraversable
+from datetime import datetime
from zope.interface import implements
from zope.interface.common.mapping import IItemMapping
from zope.component import getView
from zope.component import getViewProviding
from zope.app.traversing.browser.interfaces import IAbsoluteURL
+from zope.app.location.interfaces import ILocation
+from zope.app.location import LocationProxy
+from zope.app.form.utility import setUpEditWidgets, applyWidgetsChanges
+from zope.app.form.browser.submit import Update
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
class BrowserView(Acquisition.Explicit):
@@ -89,6 +95,91 @@
'url': context.absolute_url()
},)
+
+class EditView(BrowserView):
+ """Simple edit-view base class
+
+ Subclasses should provide a schema attribute defining the schema
+ to be edited.
+ """
+
+ errors = ()
+ update_status = None
+ label = ''
+
+ # Fall-back field names computes from schema
+ fieldNames = property(lambda self: getFieldNamesInOrder(self.schema))
+ # Fall-back template
+ generated_form = ViewPageTemplateFile('edit.pt')
+
+ def __init__(self, context, request):
+ BrowserView.__init__(self, context, request)
+ self._setUpWidgets()
+
+ def _setUpWidgets(self):
+ adapted = self.schema(self.context)
+ if adapted is not self.context:
+ if not ILocation.providedBy(adapted):
+ adapted = LocationProxy(adapted)
+ adapted.__parent__ = self.context
+ self.adapted = adapted
+ setUpEditWidgets(self, self.schema, source=self.adapted,
+ names=self.fieldNames)
+
+ def setPrefix(self, prefix):
+ for widget in self.widgets():
+ widget.setPrefix(prefix)
+
+ def widgets(self):
+ return [getattr(self, name+'_widget')
+ for name in self.fieldNames]
+
+ def changed(self):
+ # This method is overridden to execute logic *after* changes
+ # have been made.
+ pass
+
+ def update(self):
+ if self.update_status is not None:
+ # We've been called before. Just return the status we previously
+ # computed.
+ return self.update_status
+
+ status = ''
+
+ content = self.adapted
+
+ if Update in self.request.form.keys():
+ changed = False
+ try:
+ changed = applyWidgetsChanges(self, self.schema,
+ target=content, names=self.fieldNames)
+ # We should not generate events when an adapter is used.
+ # That's the adapter's job.
+ if changed and self.context is self.adapted:
+ notify(ObjectModifiedEvent(content))
+ except WidgetsError, errors:
+ self.errors = errors
+ status = _("An error occured.")
+ get_transaction().abort()
+ else:
+ setUpEditWidgets(self, self.schema, source=self.adapted,
+ ignoreStickyValues=True,
+ names=self.fieldNames)
+ if changed:
+ self.changed()
+ # XXX: Needs i18n support:
+ # formatter = self.request.locale.dates.getFormatter(
+ # 'dateTime', 'medium')
+ # status = _("Updated on ${date_time}")
+ # status.mapping = {'date_time': formatter.format(
+ # datetime.utcnow())}
+ status = "Updated on %s" % str(datetime.utcnow())
+
+ self.update_status = status
+ return status
+
+
class Macros:
implements(IItemMapping)
@@ -115,3 +206,4 @@
raise KeyError, key
class StandardMacros(BrowserView, Macros): pass
+
Modified: z3/Five/trunk/browserconfigure.py
==============================================================================
--- z3/Five/trunk/browserconfigure.py (original)
+++ z3/Five/trunk/browserconfigure.py Fri Jan 14 19:24:08 2005
@@ -25,13 +25,15 @@
from zope.app.publisher.browser.viewmeta import pages as zope_app_pages
from zope.app.component.metaconfigure import handler
from zope.app.component.interface import provideInterface
+from zope.app.form.browser.metaconfigure import BaseFormDirective
from resource import FileResourceFactory, ImageResourceFactory
from resource import PageTemplateResourceFactory
from resource import DirectoryResourceFactory
-from browser import BrowserView
+from browser import BrowserView, EditView
from metaclass import makeClass
from security import getSecurityInfo, protectClass, protectName, initializeClass
+from globalbrowsermenuservice import menuItemDirective
class FivePageTemplateFile(ViewPageTemplateFile):
@@ -298,6 +300,60 @@
args = (new_class,)
)
+
+#
+# Form generation from schema
+#
+def EditViewFactory(name, schema, label, permission, layer,
+ template, default_template, bases, for_, fields,
+ fulledit_path=None, fulledit_label=None, menu=u''):
+ s = getGlobalService(Presentation)
+ class_ = makeClassForTemplate(template, used_for=schema, bases=bases)
+ class_.schema = schema
+ class_.label = label
+ class_.fieldNames = fields
+
+ class_.fulledit_path = fulledit_path
+ if fulledit_path and (fulledit_label is None):
+ fulledit_label = "Full edit"
+
+ class_.fulledit_label = fulledit_label
+
+ class_.generated_form = ViewPageTemplateFile(default_template)
+
+ # Not the prettiest solution, but it works...
+ class_.__init__ = EditView.__init__
+# XXX: replace with proper checks
+# defineChecker(class_,
+# NamesChecker(("__call__", "__getitem__",
+# "browserDefault", "publishTraverse"),
+# permission))
+
+ s.provideView(for_, name, IBrowserRequest, class_, layer)
+
+
+class EditFormDirective(BaseFormDirective):
+
+ view = EditView
+ default_template = 'edit.pt'
+ title = 'Edit'
+
+ def _handle_menu(self):
+ if self.menu:
+ menuItemDirective(
+ self._context, self.menu, self.for_ or self.schema,
+ '@@' + self.name, self.title, permission=self.permission)
+
+ def __call__(self):
+ self._processWidgets()
+ self._handle_menu()
+ self._context.action(
+ discriminator=self._discriminator(),
+ callable=EditViewFactory,
+ args=self._args(),
+ kw={'menu': self.menu},
+ )
+
#
# mixin classes / class factories
#
@@ -341,3 +397,4 @@
class_.__used_for__ = used_for
return class_
+
Modified: z3/Five/trunk/configure.zcml
==============================================================================
--- z3/Five/trunk/configure.zcml (original)
+++ z3/Five/trunk/configure.zcml Fri Jan 14 19:24:08 2005
@@ -8,6 +8,7 @@
<include file="permissions.zcml" />
<include package="zope.app.traversing" />
+ <include package="zope.app.form.browser" />
<!-- do 'traditional' traversing by default; needed by ZPT -->
<adapter
Modified: z3/Five/trunk/meta.zcml
==============================================================================
--- z3/Five/trunk/meta.zcml (original)
+++ z3/Five/trunk/meta.zcml Fri Jan 14 19:24:08 2005
@@ -151,7 +151,7 @@
schema="zope.app.publisher.browser.metadirectives.IMenuItemDirective"
handler=".globalbrowsermenuservice.menuItemDirective"
/>
-
+
<meta:complexDirective
name="menuItems"
schema="zope.app.publisher.browser.metadirectives.IMenuItemsDirective"
@@ -162,11 +162,26 @@
name="menuItem"
schema="zope.app.publisher.browser.metadirectives.IMenuItemSubdirective"
/>
-
+
</meta:complexDirective>
-
+
+
+ <meta:complexDirective
+ name="editform"
+ schema="zope.app.form.browser.metadirectives.IEditFormDirective"
+ handler=".browserconfigure.EditFormDirective"
+ >
+
+ <meta:subdirective
+ name="widget"
+ schema="zope.app.form.browser.metadirectives.IWidgetSubdirective"
+ />
+
+ </meta:complexDirective>
+
</meta:directives>
+
<meta:directives namespace="http://namespaces.zope.org/five">
<!-- specific to Five -->
Modified: z3/Five/trunk/tests/products/FiveTest/__init__.py
==============================================================================
--- z3/Five/trunk/tests/products/FiveTest/__init__.py (original)
+++ z3/Five/trunk/tests/products/FiveTest/__init__.py Fri Jan 14 19:24:08 2005
@@ -22,6 +22,15 @@
)
context.registerClass(
- fancycontent.FancyContent,
- constructors = (fancycontent.manage_addFancyContent,)
- )
+ fancycontent.FancyContent,
+ constructors = (fancycontent.manage_addFancyContent,)
+ )
+
+ context.registerClass(
+ simplecontent.FieldSimpleContent,
+ constructors = (simplecontent.manage_addFieldSimpleContentForm,
+ simplecontent.manage_addFieldSimpleContent,)
+ )
+
+
+
Modified: z3/Five/trunk/tests/products/FiveTest/configure.zcml
==============================================================================
--- z3/Five/trunk/tests/products/FiveTest/configure.zcml (original)
+++ z3/Five/trunk/tests/products/FiveTest/configure.zcml Fri Jan 14 19:24:08 2005
@@ -283,6 +283,16 @@
permission="zope2.ViewManagementScreens"
/>
+ <!-- browser forms -->
+ <five:traversable class=".simplecontent.FieldSimpleContent" />
+
+ <browser:editform
+ schema=".interfaces.IFieldSimpleContent"
+ for=".interfaces.IFieldSimpleContent"
+ name="edit.html"
+ permission="zope2.Public"
+ />
+
<!-- stuff that we'll override in overrides.zcml -->
<browser:page
@@ -308,7 +318,7 @@
attribute="method"
permission="zope2.Public"
/>
-
+
<!-- browser menu support -->
<browser:menu
id="testmenu"
@@ -326,23 +336,23 @@
<browser:menuItems
for=".interfaces.ISimpleContent"
menu="testmenu">
-
+
<menuItem
title="Test Menu Item 2"
action="parakeet.html"
description="This is a test menu item"
permission="zope2.Public"
/>
-
+
<menuItem
title="Test Menu Item 3"
action="falcon.html"
description="This is a test menu item"
permission="zope2.Public"
/>
-
+
</browser:menuItems>
-
+
<!-- subscribe to all events -->
<five:sendEvents
class=".simplecontent.SimpleContent"
Modified: z3/Five/trunk/tests/products/FiveTest/interfaces.py
==============================================================================
--- z3/Five/trunk/tests/products/FiveTest/interfaces.py (original)
+++ z3/Five/trunk/tests/products/FiveTest/interfaces.py Fri Jan 14 19:24:08 2005
@@ -1,4 +1,5 @@
from zope.interface import Interface
+from zope.schema import Text, TextLine
class IAdaptable(Interface):
"""This is a Zope 3 interface.
@@ -35,3 +36,16 @@
class IFancyContent(Interface):
pass
+
+class IFieldSimpleContent(ISimpleContent):
+ title = TextLine(
+ title=u"Title",
+ description=u"A short description of the event.",
+ default=u"",
+ required=True)
+
+ description = Text(
+ title=u"Description",
+ description=u"A long description of the event.",
+ default=u"",
+ required=False)
Modified: z3/Five/trunk/tests/products/FiveTest/simplecontent.py
==============================================================================
--- z3/Five/trunk/tests/products/FiveTest/simplecontent.py (original)
+++ z3/Five/trunk/tests/products/FiveTest/simplecontent.py Fri Jan 14 19:24:08 2005
@@ -5,7 +5,7 @@
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from zope.interface import implements
from interfaces import ISimpleContent, ICallableSimpleContent,\
- IIndexSimpleContent
+ IIndexSimpleContent, IFieldSimpleContent
class SimpleContent(SimpleItem):
implements(ISimpleContent)
@@ -49,6 +49,13 @@
""" """
return "Default index_html called"
+class FieldSimpleContent(SimpleContent):
+ """A Viewable piece of content with fields"""
+ implements(IFieldSimpleContent)
+
+ meta_type = 'Five FieldSimpleContent'
+
+InitializeClass(FieldSimpleContent)
manage_addSimpleContentForm = PageTemplateFile(
"www/simpleContentAdd", globals(),
@@ -71,3 +78,13 @@
id = self._setObject(id, IndexSimpleContent(id, title))
add_and_edit(self, id, REQUEST)
return ''
+
+manage_addFieldSimpleContentForm = PageTemplateFile(
+ "www/fieldSimpleContentAdd", globals(),
+ __name__ = 'manage_addFieldSimpleContentForm')
+
+def manage_addFieldSimpleContent(self, id, title, REQUEST=None):
+ """Add the viewable simple content."""
+ id = self._setObject(id, FieldSimpleContent(id, title))
+ add_and_edit(self, id, REQUEST)
+ return ''
More information about the z3-checkins
mailing list