[z3-checkins] r8668 - in z3/Five/branch/regebro-addform_directive:
. tests/products/FiveTest tests/products/FiveTest/www
regebro at codespeak.net
regebro at codespeak.net
Fri Jan 28 18:08:19 MET 2005
Author: regebro
Date: Fri Jan 28 18:08:19 2005
New Revision: 8668
Added:
z3/Five/branch/regebro-addform_directive/add.pt (contents, props changed)
z3/Five/branch/regebro-addform_directive/tests/products/FiveTest/www/fieldSimpleContentAdd.zpt (contents, props changed)
Modified:
z3/Five/branch/regebro-addform_directive/browser.py
z3/Five/branch/regebro-addform_directive/browserconfigure.py
z3/Five/branch/regebro-addform_directive/edit.pt
z3/Five/branch/regebro-addform_directive/meta.zcml
z3/Five/branch/regebro-addform_directive/metaconfigure.py
z3/Five/branch/regebro-addform_directive/tests/products/FiveTest/configure.zcml
Log:
addform + factory directive
Added: z3/Five/branch/regebro-addform_directive/add.pt
==============================================================================
--- (empty file)
+++ z3/Five/branch/regebro-addform_directive/add.pt Fri Jan 28 18:08:19 2005
@@ -0,0 +1,70 @@
+<html>
+ <body>
+
+ <div metal:define-macro="addform">
+
+ <form action="." tal:attributes="action request/URL" method="post"
+ enctype="multipart/form-data">
+
+ <div metal:define-macro="formbody">
+
+ <h3 tal:condition="view/label"
+ tal:content="view/label"
+ metal:define-slot="heading"
+ >Edit something</h3>
+
+ <p tal:define="status view/update"
+ tal:condition="status"
+ tal:content="status" />
+
+ <p tal:condition="view/errors" i18n:translate="">
+ There are <strong tal:content="python:len(view.errors)"
+ i18n:name="num_errors">6</strong> input errors.
+ </p>
+
+ <div metal:define-slot="extra_info" tal:replace="nothing">
+ </div>
+
+ <div class="row" metal:define-slot="extra_top" tal:replace="nothing">
+ <div class="label">Extra top</div>
+ <div class="label"><input type="text" style="width:100%" /></div>
+ </div>
+
+ <div metal:use-macro="context/@@widget_macros/widget_rows" />
+
+ <div class="separator"></div>
+
+ <div class="row"
+ metal:define-slot="extra_bottom" tal:replace="nothing">
+ <div class="label">Extra bottom</div>
+ <div class="field"><input type="text" style="width:100%" /></div>
+ </div>
+
+ <div class="separator"></div>
+
+ </div>
+ <br/><br/>
+ <div class="row">
+ <div class="controls"><hr />
+ <input type='submit' value='Refresh'
+ i18n:attributes='value refresh-button' />
+ <input type='submit' value='Add' name='UPDATE_SUBMIT'
+ i18n:attributes='value add-button' />
+ <span tal:condition="context/nameAllowed|nothing" tal:omit-tag="">
+ <b i18n:translate="">Object Name</b>
+ <input type='text' name='add_input_name'
+ tal:attributes="value context/contentName" />
+ </span>
+ </div>
+ </div>
+
+ <div class="row" metal:define-slot="extra_buttons" tal:replace="nothing">
+ </div>
+
+ <div class="separator"></div>
+ </form>
+ </div>
+ </body>
+
+</html>
+
Modified: z3/Five/branch/regebro-addform_directive/browser.py
==============================================================================
--- z3/Five/branch/regebro-addform_directive/browser.py (original)
+++ z3/Five/branch/regebro-addform_directive/browser.py Fri Jan 28 18:08:19 2005
@@ -25,8 +25,12 @@
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.utility import setUpWidgets, getWidgetsData
from zope.app.form.browser.submit import Update
+from zope.app.form.interfaces import IInputWidget, WidgetsError
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.event import notify
+from zope.app.event.objectevent import ObjectCreatedEvent
class BrowserView(Acquisition.Explicit):
@@ -160,7 +164,7 @@
notify(ObjectModifiedEvent(content))
except WidgetsError, errors:
self.errors = errors
- status = _("An error occured.")
+ status = "An error occured."
get_transaction().abort()
else:
setUpEditWidgets(self, self.schema, source=self.adapted,
@@ -179,6 +183,282 @@
self.update_status = status
return status
+class AddView(EditView):
+ """Simple edit-view base class.
+
+ Subclasses should provide a schema attribute defining the schema
+ to be edited.
+ """
+
+ def _setUpWidgets(self):
+ setUpWidgets(self, self.schema, IInputWidget, names=self.fieldNames)
+
+ def update(self):
+
+ if self.update_status is not None:
+ # We've been called before. Just return the previous result.
+ return self.update_status
+
+ if Update in self.request.form.keys():
+
+ self.update_status = ''
+ try:
+ data = getWidgetsData(self, self.schema, names=self.fieldNames)
+ self.createAndAdd(data)
+ except WidgetsError, errors:
+ self.errors = errors
+ self.update_status = "An error occured."
+ return self.update_status
+
+ self.request.response.redirect(self.context.absolute_url())
+
+ return self.update_status
+
+ def create(self, *args, **kw):
+ """Do the actual instantiation."""
+ return self._factory(*args, **kw)
+
+ def createAndAdd(self, data):
+ """Add the desired object using the data in the data argument.
+
+ The data argument is a dictionary with the data entered in the form.
+ """
+ args = []
+ if self._arguments:
+ for name in self._arguments:
+ args.append(data[name])
+
+ kw = {}
+ if self._keyword_arguments:
+ for name in self._keyword_arguments:
+ if name in data:
+ kw[str(name)] = data[name]
+
+ content = self.create(*args, **kw)
+ adapted = self.schema(content)
+
+ errors = []
+
+ if self._set_before_add:
+ for name in self._set_before_add:
+ if name in data:
+ field = self.schema[name]
+ try:
+ field.set(adapted, data[name])
+ except ValidationError:
+ errors.append(sys.exc_info()[1])
+
+ if errors:
+ raise WidgetsError(*errors)
+
+ notify(ObjectCreatedEvent(content))
+
+ content = self.add(content)
+
+ adapted = self.schema(content)
+
+ if self._set_after_add:
+ for name in self._set_after_add:
+ if name in data:
+ field = self.schema[name]
+ try:
+ field.set(adapted, data[name])
+ except ValidationError:
+ errors.append(sys.exc_info()[1])
+
+ if errors:
+ raise WidgetsError(*errors)
+
+ return content
+
+ def add(self, content):
+ self.context._setObject(content.getId(), content)
+ return self.context._getOb(content.getId())
+
+class AddView(EditView):
+ """Simple edit-view base class.
+
+ Subclasses should provide a schema attribute defining the schema
+ to be edited.
+ """
+
+ def _setUpWidgets(self):
+ setUpWidgets(self, self.schema, IInputWidget, names=self.fieldNames)
+
+ def update(self):
+
+ if self.update_status is not None:
+ # We've been called before. Just return the previous result.
+ return self.update_status
+
+ if Update in self.request.form.keys():
+
+ self.update_status = ''
+ try:
+ data = getWidgetsData(self, self.schema, names=self.fieldNames)
+ self.createAndAdd(data)
+ except WidgetsError, errors:
+ self.errors = errors
+ self.update_status = "An error occured."
+ return self.update_status
+
+ self.request.response.redirect(self.context.absolute_url())
+
+ return self.update_status
+
+ def create(self, *args, **kw):
+ """Do the actual instantiation."""
+ return self._factory(*args, **kw)
+
+ def createAndAdd(self, data):
+ """Add the desired object using the data in the data argument.
+
+ The data argument is a dictionary with the data entered in the form.
+ """
+ args = []
+ if self._arguments:
+ for name in self._arguments:
+ args.append(data[name])
+
+ kw = {}
+ if self._keyword_arguments:
+ for name in self._keyword_arguments:
+ if name in data:
+ kw[str(name)] = data[name]
+
+ content = self.create(*args, **kw)
+ adapted = self.schema(content)
+
+ errors = []
+
+ if self._set_before_add:
+ for name in self._set_before_add:
+ if name in data:
+ field = self.schema[name]
+ try:
+ field.set(adapted, data[name])
+ except ValidationError:
+ errors.append(sys.exc_info()[1])
+
+ if errors:
+ raise WidgetsError(*errors)
+
+ notify(ObjectCreatedEvent(content))
+
+ content = self.add(content)
+
+ adapted = self.schema(content)
+
+ if self._set_after_add:
+ for name in self._set_after_add:
+ if name in data:
+ field = self.schema[name]
+ try:
+ field.set(adapted, data[name])
+ except ValidationError:
+ errors.append(sys.exc_info()[1])
+
+ if errors:
+ raise WidgetsError(*errors)
+
+ return content
+
+ def add(self, content):
+ self.context._setObject(content.getId(), content)
+ return self.context._getOb(content.getId())
+
+class AddView(EditView):
+ """Simple edit-view base class.
+
+ Subclasses should provide a schema attribute defining the schema
+ to be edited.
+ """
+
+ def _setUpWidgets(self):
+ setUpWidgets(self, self.schema, IInputWidget, names=self.fieldNames)
+
+ def update(self):
+
+ if self.update_status is not None:
+ # We've been called before. Just return the previous result.
+ return self.update_status
+
+ if Update in self.request.form.keys():
+
+ self.update_status = ''
+ try:
+ data = getWidgetsData(self, self.schema, names=self.fieldNames)
+ self.createAndAdd(data)
+ except WidgetsError, errors:
+ self.errors = errors
+ self.update_status = "An error occured."
+ return self.update_status
+
+ self.request.response.redirect(self.context.absolute_url())
+
+ return self.update_status
+
+ def create(self, *args, **kw):
+ """Do the actual instantiation."""
+ return self._factory(*args, **kw)
+
+ def createAndAdd(self, data):
+ """Add the desired object using the data in the data argument.
+
+ The data argument is a dictionary with the data entered in the form.
+ """
+ args = []
+ if self._arguments:
+ for name in self._arguments:
+ args.append(data[name])
+
+ kw = {}
+ if self._keyword_arguments:
+ for name in self._keyword_arguments:
+ if name in data:
+ kw[str(name)] = data[name]
+
+ content = self.create(*args, **kw)
+ adapted = self.schema(content)
+
+ errors = []
+
+ if self._set_before_add:
+ for name in self._set_before_add:
+ if name in data:
+ field = self.schema[name]
+ try:
+ field.set(adapted, data[name])
+ except ValidationError:
+ errors.append(sys.exc_info()[1])
+
+ if errors:
+ raise WidgetsError(*errors)
+
+ notify(ObjectCreatedEvent(content))
+
+ content = self.add(content)
+
+ adapted = self.schema(content)
+
+ if self._set_after_add:
+ for name in self._set_after_add:
+ if name in data:
+ field = self.schema[name]
+ try:
+ field.set(adapted, data[name])
+ except ValidationError:
+ errors.append(sys.exc_info()[1])
+
+ if errors:
+ raise WidgetsError(*errors)
+
+ return content
+
+ def add(self, content):
+ self.context._setObject(content.getId(), content)
+ return self.context._getOb(content.getId())
+
class Macros:
Modified: z3/Five/branch/regebro-addform_directive/browserconfigure.py
==============================================================================
--- z3/Five/branch/regebro-addform_directive/browserconfigure.py (original)
+++ z3/Five/branch/regebro-addform_directive/browserconfigure.py Fri Jan 28 18:08:19 2005
@@ -13,7 +13,7 @@
$Id$
"""
-import os
+import os, sys
from zope.interface import Interface
from zope.component import getGlobalService, ComponentLookupError
@@ -25,12 +25,13 @@
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.container.interfaces import IAdding
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, EditView
+from browser import BrowserView, EditView, AddView
from metaclass import makeClass
from security import getSecurityInfo, protectClass, protectName, initializeClass
from globalbrowsermenuservice import menuItemDirective
@@ -374,6 +375,129 @@
kw={'menu': self.menu},
)
+
+def AddViewFactory(name, schema, label, permission, layer,
+ template, default_template, bases, for_,
+ fields, content_factory, arguments,
+ keyword_arguments, set_before_add, set_after_add,
+ menu=u''):
+
+ s = getGlobalService(Presentation)
+ class_ = makeClassForTemplate(template, used_for=schema, bases=bases)
+
+ class_.schema = schema
+ class_.label = label
+ class_.fieldNames = fields
+ class_._factory = content_factory
+ class_._arguments = arguments
+ class_._keyword_arguments = keyword_arguments
+ class_._set_before_add = set_before_add
+ class_._set_after_add = set_after_add
+
+ class_.generated_form = ViewPageTemplateFile(default_template)
+
+# defineChecker(class_,
+# NamesChecker(
+# ("__call__", "__getitem__",
+# "browserDefault", "publishTraverse"),
+# permission,
+# )
+# )
+
+ s.provideView(for_, name, IBrowserRequest, class_, layer)
+
+class AddFormDirective(BaseFormDirective):
+
+ view = AddView
+ default_template = 'add.pt'
+ for_ = IAdding
+
+ # default add form information
+ description = None
+ content_factory = None
+ arguments = None
+ keyword_arguments = None
+ set_before_add = None
+ set_after_add = None
+
+ def _handle_menu(self):
+ if self.menu or self.title:
+ if (not self.menu) or (not self.title):
+ raise ValueError("If either menu or title are specified, "
+ "they must both be specified")
+ # Add forms are really for IAdding components, so do not use
+ # for=self.schema.
+ menuItemDirective(
+ self._context, self.menu, self.for_, '@@' + self.name,
+ self.title, permission=self.permission,
+ description=self.description)
+
+ def _handle_arguments(self, leftover=None):
+ schema = self.schema
+ fields = self.fields
+ arguments = self.arguments
+ keyword_arguments = self.keyword_arguments
+ set_before_add = self.set_before_add
+ set_after_add = self.set_after_add
+
+ if leftover is None:
+ leftover = fields
+
+ if arguments:
+ missing = [n for n in arguments if n not in fields]
+ if missing:
+ raise ValueError("Some arguments are not included in the form",
+ missing)
+ optional = [n for n in arguments if not schema[n].required]
+ if optional:
+ raise ValueError("Some arguments are optional, use"
+ " keyword_arguments for them",
+ optional)
+ leftover = [n for n in leftover if n not in arguments]
+
+ if keyword_arguments:
+ missing = [n for n in keyword_arguments if n not in fields]
+ if missing:
+ raise ValueError(
+ "Some keyword_arguments are not included in the form",
+ missing)
+ leftover = [n for n in leftover if n not in keyword_arguments]
+
+ if set_before_add:
+ missing = [n for n in set_before_add if n not in fields]
+ if missing:
+ raise ValueError(
+ "Some set_before_add are not included in the form",
+ missing)
+ leftover = [n for n in leftover if n not in set_before_add]
+
+ if set_after_add:
+ missing = [n for n in set_after_add if n not in fields]
+ if missing:
+ raise ValueError(
+ "Some set_after_add are not included in the form",
+ missing)
+ leftover = [n for n in leftover if n not in set_after_add]
+
+ self.set_after_add += leftover
+
+ else:
+ self.set_after_add = leftover
+
+ def __call__(self):
+ self._processWidgets()
+ self._handle_menu()
+ self._handle_arguments()
+
+ self._context.action(
+ discriminator=self._discriminator(),
+ callable=AddViewFactory,
+ args=self._args()+(self.content_factory, self.arguments,
+ self.keyword_arguments,
+ self.set_before_add, self.set_after_add),
+ kw={'menu': self.menu},
+ )
+
#
# mixin classes / class factories
#
Modified: z3/Five/branch/regebro-addform_directive/edit.pt
==============================================================================
--- z3/Five/branch/regebro-addform_directive/edit.pt (original)
+++ z3/Five/branch/regebro-addform_directive/edit.pt Fri Jan 28 18:08:19 2005
@@ -1,7 +1,6 @@
<tal:tag condition="view/update"/>
-<html>
- <body>
- <div>
+<html metal:use-macro="here/main_template/macros/master">
+ <body metal:fill-slot="main">
<div metal:define-macro="body">
@@ -61,8 +60,6 @@
</form>
</div>
-
- </div>
</body>
</html>
Modified: z3/Five/branch/regebro-addform_directive/meta.zcml
==============================================================================
--- z3/Five/branch/regebro-addform_directive/meta.zcml (original)
+++ z3/Five/branch/regebro-addform_directive/meta.zcml Fri Jan 28 18:08:19 2005
@@ -79,8 +79,19 @@
schema="zope.app.component.metadirectives.IAllowSubdirective"
/>
+ <meta:subdirective
+ name="factory"
+ schema="zope.app.component.metadirectives.IFactorySubdirective"
+ />
+
</meta:complexDirective>
+ <meta:directive
+ name="factory"
+ schema="zope.app.component.metadirectives.IFactoryDirective"
+ handler="zope.app.component.metaconfigure.factory"
+ />
+
</meta:directives>
<meta:directives namespace="http://namespaces.zope.org/browser">
@@ -179,6 +190,19 @@
</meta:complexDirective>
+ <meta:complexDirective
+ name="addform"
+ schema="zope.app.form.browser.metadirectives.IAddFormDirective"
+ handler=".browserconfigure.AddFormDirective"
+ >
+
+ <meta:subdirective
+ name="widget"
+ schema="zope.app.form.browser.metadirectives.IWidgetSubdirective"
+ />
+
+ </meta:complexDirective>
+
</meta:directives>
Modified: z3/Five/branch/regebro-addform_directive/metaconfigure.py
==============================================================================
--- z3/Five/branch/regebro-addform_directive/metaconfigure.py (original)
+++ z3/Five/branch/regebro-addform_directive/metaconfigure.py Fri Jan 28 18:08:19 2005
@@ -14,6 +14,8 @@
from zope.interface import classImplements
from zope.configuration.exceptions import ConfigurationError
+from zope.component.factory import Factory
+from zope.app.component.metaconfigure import factory
from security import CheckerPublic
from security import protectName, initializeClass
@@ -80,3 +82,16 @@
callable = initializeClass,
args = (self.__class,)
)
+
+ def factory(self, _context, id=None, title="", description=''):
+ """Register a zmi factory for this class"""
+
+ id = id or self.__id
+ factoryObj = Factory(self.__class, title, description)
+
+ # note factories are all in one pile, services and content,
+ # so addable names must also act as if they were all in the
+ # same namespace, despite the service/content division
+ factory(_context, factoryObj, id, title, description)
+
+
Modified: z3/Five/branch/regebro-addform_directive/tests/products/FiveTest/configure.zcml
==============================================================================
--- z3/Five/branch/regebro-addform_directive/tests/products/FiveTest/configure.zcml (original)
+++ z3/Five/branch/regebro-addform_directive/tests/products/FiveTest/configure.zcml Fri Jan 28 18:08:19 2005
@@ -293,6 +293,12 @@
permission="zope2.Public"
/>
+ <browser:addform
+ schema=".interfaces.IFieldSimpleContent"
+ for=".interfaces.IFieldSimpleContent"
+ name="add.html"
+ permission="zope2.Public"
+ />
<!-- stuff that we'll override in overrides.zcml -->
<browser:page
Added: z3/Five/branch/regebro-addform_directive/tests/products/FiveTest/www/fieldSimpleContentAdd.zpt
==============================================================================
--- (empty file)
+++ z3/Five/branch/regebro-addform_directive/tests/products/FiveTest/www/fieldSimpleContentAdd.zpt Fri Jan 28 18:08:19 2005
@@ -0,0 +1,45 @@
+<h1 tal:replace="structure here/manage_page_header">Header</h1>
+
+<h2 tal:define="form_title string:Add Field Simple Content"
+ tal:replace="structure here/manage_form_title">Form Title</h2>
+
+<p class="form-help">
+Add Simple Content
+</p>
+
+<form action="manage_addFieldSimpleContent" method="post">
+<table cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="id" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Title
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="title" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ </td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <input class="form-element" type="submit" name="submit_add"
+ value=" Add " />
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+
+<h1 tal:replace="structure here/manage_page_footer">Footer</h1>
More information about the z3-checkins
mailing list