[Checkins] SVN: z3c.reference/branches/flash/src/z3c/reference/
refactored to generic form serialization
Bernd Dorn
bernd.dorn at lovelysystems.com
Fri Sep 7 08:20:30 EDT 2007
Log message for revision 79521:
refactored to generic form serialization
Changed:
U z3c.reference/branches/flash/src/z3c/reference/README.txt
U z3c.reference/branches/flash/src/z3c/reference/browser/README.txt
A z3c.reference/branches/flash/src/z3c/reference/browser/serialize.py
A z3c.reference/branches/flash/src/z3c/reference/browser/serialize.txt
U z3c.reference/branches/flash/src/z3c/reference/browser/tests.py
U z3c.reference/branches/flash/src/z3c/reference/browser/views.py
U z3c.reference/branches/flash/src/z3c/reference/browser/widget.py
U z3c.reference/branches/flash/src/z3c/reference/interfaces.py
-=-
Modified: z3c.reference/branches/flash/src/z3c/reference/README.txt
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/README.txt 2007-09-07 12:15:50 UTC (rev 79520)
+++ z3c.reference/branches/flash/src/z3c/reference/README.txt 2007-09-07 12:20:29 UTC (rev 79521)
@@ -139,6 +139,7 @@
ValueError: ('viewReferences', 'field is readonly')
+
ViewReferenceSettings
---------------------
Modified: z3c.reference/branches/flash/src/z3c/reference/browser/README.txt
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/browser/README.txt 2007-09-07 12:15:50 UTC (rev 79520)
+++ z3c.reference/branches/flash/src/z3c/reference/browser/README.txt 2007-09-07 12:20:29 UTC (rev 79521)
@@ -8,14 +8,19 @@
>>> from z3c.reference.browser.widget import ViewReferenceWidget
>>> from z3c.reference.schema import ViewReferenceField
+At first we need an interface for the context our widget used for. The
+`ìntro`` filed defines a settingName which is used by the widget to
+get information about which edit form for the reference should
+be used.
+
>>> class IPage(zope.interface.Interface):
... """Interface for a page."""
...
... intro = ViewReferenceField(title=u'Intro',
... description=u'A intro text',
- ... settingName=u'')
+ ... settingName=u'introRefs')
-Let's define the IPage object:
+Let's create an IPage implementation.
>>> class Page(object):
...
@@ -47,21 +52,10 @@
>>> boundField = field.bind(page)
>>> widget = ViewReferenceWidget(boundField, request)
-Now let's see how such a widget looks like if we render them::
+Now let's see how such a widget looks like if we render it with no value.
- >>> print widget() # doctest: +NORMALIZE_WHITESPACE
- <a class="popupwindow"
- href="http://127.0.0.1/Intro/viewReferenceEditor.html?name=field.intro&target=&settingName=&view="
- id="field.intro.tag" name="field.intro" onclick="" title="Undefined"
- rel="window">Undefined</a><input class="hiddenType"
- id="field.intro.view" name="field.intro.view" type="hidden" value=""
- rel="window" /><input class="hiddenType" id="field.intro.target"
- name="field.intro.target" type="hidden" value="" rel="window"
- /><input class="hiddenType" id="field.intro.title"
- name="field.intro.title" type="hidden" value="" rel="window"
- /><input class="hiddenType" id="field.intro.description"
- name="field.intro.description" type="hidden" value="" rel="window"
- />
+ >>> print widget()
+ <a class="popupwindow" href="http://127.0.0.1/Intro/viewReferenceEditor.html?target=&settingName=introRefs&name=field.intro" id="field.intro.tag" name="field.intro" onclick="" title="Undefined" rel="window">Undefined</a><input class="hiddenType" id="field.intro.target" name="field.intro.target" type="hidden" value="" rel="window" /><input class="hiddenType" id="field.intro.formData" name="field.intro.formData" type="hidden" value="" rel="window" />
If we store a empty request/form we will get the following error::
@@ -89,12 +83,78 @@
>>> intids = zope.component.getUtility(IIntIds)
>>> oid = intids.register(text)
+Let us assign the text object here, so we can look at what the widget
+renders if a target is defined.
+
+ >>> from z3c.reference.reference import ViewReference
+ >>> vr = ViewReference()
+ >>> vr.target = text
+ >>> page.intro = vr
+
+ >>> field = IPage['intro']
+ >>> boundField = field.bind(page)
+ >>> request = TestRequest()
+ >>> widget = ViewReferenceWidget(boundField, request)
+ >>> widget.setRenderedValue(page.intro)
+ >>> print widget()
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: ((<Text object at ...>,
+ <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+ <InterfaceClass z3c.reference.interfaces.IViewReferenceEditor>, u'introRefs')
+
+Ups, we get an Error. We need a editor form for the given settings for
+the target object. Let's create one that edits basic dublin core data.
+
+ >>> from zope.formlib import form
+ >>> from zope.dublincore.interfaces import IZopeDublinCore
+ >>> from z3c.reference.interfaces import IViewReference
+ >>> class IntroRefsEditForm(form.EditForm):
+ ... form_fields = form.Fields(IZopeDublinCore,
+ ... IViewReference).select('title', 'description', 'view')
+
+And register it ...
+
+ >>> from z3c.reference.interfaces import IViewReferenceEditor
+ >>> from zope.publisher.interfaces.browser import IBrowserRequest
+ >>> zope.component.provideAdapter(IntroRefsEditForm,
+ ... (zope.interface.Interface, IBrowserRequest),
+ ... IViewReferenceEditor,
+ ... name=u'introRefs')
+
+We also need to register the widgets.
+
+ >>> from zope.schema.interfaces import ITextLine, IText
+ >>> from zope.app.form.browser import TextWidget, TextAreaWidget
+ >>> from zope.app.form.browser.interfaces import ISimpleInputWidget
+ >>> from zope.app.form.browser.interfaces import ITextBrowserWidget
+ >>> zope.component.provideAdapter(TextWidget,
+ ... (ITextLine, IBrowserRequest), ITextBrowserWidget)
+ >>> zope.component.provideAdapter(TextAreaWidget,
+ ... (IText, IBrowserRequest), ISimpleInputWidget)
+
+So there is no formData for now, because we have no data on the reference.
+
+
+ >>> print widget()
+ <...name="field.intro.formData"
+ ...value="form.title=&form.view=&form.description="...
+
+Let us write some data to it.
+
+ >>> IZopeDublinCore(vr).title = u"The DC Title"
+ >>> IZopeDublinCore(vr).description = u"The DC Description"
+ >>> print widget()
+ <...
+ value="form.title=The+DC+Title&form.view=&form.description=The+DC+Description"...
+
Now we can setup a test request and set the values for the widget:
+
+ >>> formData = 'form.view=resized&form.title=New+Title&form.description=New+Description'
>>> form={'field.intro.target': oid,
- ... 'field.intro.view': 'ratio=16x9',
- ... 'field.intro.title': 'My reference',
- ... 'field.intro.description': 'This is a reference'}
- >>> request = TestRequest(HTTP_ACCEPT_LANGUAGE='pl', form=form)
+ ... 'field.intro.formData': formData}
+
+ >>> request = TestRequest(form=form)
>>> widget = ViewReferenceWidget(boundField, request)
>>> reference = widget._toFieldValue(form)
>>> reference
@@ -103,14 +163,14 @@
>>> reference.target is text
True
- >>> reference.view
- u'ratio=16x9'
+ >>> IZopeDublinCore(reference).title
+ u'New Title'
- >>> reference.title
- u'My reference'
+ >>> IZopeDublinCore(reference).description
+ u'New Description'
- >>> reference.description
- u'This is a reference'
+ >>> reference.view
+ u'resized'
Let's save the new reference:
Added: z3c.reference/branches/flash/src/z3c/reference/browser/serialize.py
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/browser/serialize.py (rev 0)
+++ z3c.reference/branches/flash/src/z3c/reference/browser/serialize.py 2007-09-07 12:20:29 UTC (rev 79521)
@@ -0,0 +1,22 @@
+import cElementTree
+import urllib
+def serializeForm(html):
+
+ html = '<div>%s</div>' % html
+ elem = cElementTree.fromstring(html)
+ res = []
+ for e in elem.findall('input'):
+ name = e.get('name')
+ value = e.get('value')
+ t = e.get('type')
+ if t not in ('hidden', 'text') or None in (name, value):
+ continue
+ res.append((name, value))
+ for e in elem.findall('textarea'):
+ name = e.get('name')
+ value = e.text or ''
+ if name is None:
+ continue
+ res.append((name, value))
+ return urllib.urlencode(res)
+
Property changes on: z3c.reference/branches/flash/src/z3c/reference/browser/serialize.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.reference/branches/flash/src/z3c/reference/browser/serialize.txt
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/browser/serialize.txt (rev 0)
+++ z3c.reference/branches/flash/src/z3c/reference/browser/serialize.txt 2007-09-07 12:20:29 UTC (rev 79521)
@@ -0,0 +1,15 @@
+=================
+ Form serializer
+=================
+
+Serializes a form to a query string.
+
+ >>> from z3c.reference.browser.serialize import serializeForm
+
+ >>> html = """<input type="text" value="one" name="m.one"/><br/>"""\
+ ... """<input type="text" value="two" name="m.two"/>""" \
+ ... """<textarea name="m.area">tarea</textarea>""" \
+ ... """<input type="text" value="second" name="m.two"/>"""
+ >>> print serializeForm(html)
+ m.one=one&m.two=two&m.two=second&m.area=tarea
+
Property changes on: z3c.reference/branches/flash/src/z3c/reference/browser/serialize.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: z3c.reference/branches/flash/src/z3c/reference/browser/tests.py
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/browser/tests.py 2007-09-07 12:15:50 UTC (rev 79520)
+++ z3c.reference/branches/flash/src/z3c/reference/browser/tests.py 2007-09-07 12:20:29 UTC (rev 79521)
@@ -64,6 +64,10 @@
def test_suite():
return unittest.TestSuite((
+ DocFileSuite('serialize.txt',
+ setUp=setUp,tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
DocFileSuite('README.txt',
setUp=setUp,tearDown=tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
Modified: z3c.reference/branches/flash/src/z3c/reference/browser/views.py
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/browser/views.py 2007-09-07 12:15:50 UTC (rev 79520)
+++ z3c.reference/branches/flash/src/z3c/reference/browser/views.py 2007-09-07 12:20:29 UTC (rev 79521)
@@ -144,6 +144,11 @@
return u''
+def getEditorView(target, request, settingName):
+ return component.getMultiAdapter(
+ (target, request),
+ interfaces.IViewReferenceEditor, name=settingName)
+
class ViewReferenceEditorDispatcher(object):
"""Return the edit IViewReferenceEditor for the target context
@@ -170,8 +175,6 @@
intids = component.getUtility(IIntIds)
obj = intids.queryObject(int(self.targetStr))
if obj is not None and self.settingNameStr is not None:
- view = component.queryMultiAdapter((obj, self.request),
- interfaces.IViewReferenceEditor, name=self.settingNameStr)
- if view is not None:
- return view()
+ view = getEditorView(obj, self.request, self.settingNameStr)
+ return view()
return u''
Modified: z3c.reference/branches/flash/src/z3c/reference/browser/widget.py
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/browser/widget.py 2007-09-07 12:15:50 UTC (rev 79520)
+++ z3c.reference/branches/flash/src/z3c/reference/browser/widget.py 2007-09-07 12:20:29 UTC (rev 79521)
@@ -23,7 +23,7 @@
from zope.traversing.browser import absoluteURL
from zope.traversing.interfaces import TraversalError
from zope.cachedescriptors.property import Lazy
-
+from zope.publisher.browser import TestRequest
from zope.app.intid.interfaces import IIntIds
from zope.app.form.browser.widget import SimpleInputWidget
from zope.app.form.browser.textwidgets import TextWidget
@@ -33,6 +33,8 @@
from zc import resourcelibrary
from z3c.reference import interfaces
from z3c.reference.reference import ViewReference,ImageReference
+from views import getEditorView
+from serialize import serializeForm
untitled = u'No Link defined'
undefined = u'Undefined'
@@ -48,7 +50,6 @@
rc = rc + node.data
return rc
-
class ViewReferenceWidget(TextWidget):
"""renders an "a" tag with the title and href attributes."""
@@ -70,12 +71,29 @@
"""Returns the refrence explorer url."""
return absoluteURL(self.context.context, self.request) + '/%s?%s' % (
self.referenceExplorerViewName,
- urllib.urlencode({'settingName': self.context.settingName,
- 'target': self.targetValue,
- 'view': self.viewValue,
- 'name': self.name}))
+ urllib.urlencode({'settingName' : self.context.settingName,
+ 'target' : self.targetValue,
+ 'name': self.name}))
@property
+ def formDataValue(self):
+ vr = self._getCurrentValue()
+ if vr is None or vr.target is None:
+ return ''
+ klass = getEditorView(vr.target, self.request,
+ self.context.settingName).__class__
+
+
+ view = klass(vr, TestRequest())
+ view.resetForm()
+ html = ''
+ for widget in view.widgets:
+ v = widget()
+ html += v
+ qs = serializeForm(html)
+ return qs
+
+ @property
def viewValue(self):
"""Returns the reference view string."""
current = self._getCurrentValue()
@@ -90,8 +108,8 @@
target = u''
current = self._getCurrentValue()
if current and current.target:
- intIds = component.getUtility(IIntIds)
- target = intIds.getId(current.target)
+ intIds = zope.component.getUtility(IIntIds)
+ target = intIds.getId(current.target)
return target
@property
@@ -103,15 +121,6 @@
else:
return u''
- @property
- def descriptionValue(self):
- """Returns the reference description."""
- current = self._getCurrentValue()
- if current and current.description:
- return current.description or u''
- else:
- return u''
-
def __call__(self):
resourcelibrary.need('z3c.reference')
if self._renderedValueSet():
@@ -127,33 +136,19 @@
ref = self._emptyReference
contents = undefined
targetName = self.name + '.target'
- viewName = self.name + '.view'
- titleName = self.name + '.title'
- descriptionName = self.name + '.description'
+ formDataName = self.name + '.formData'
intidInput = renderElement(u'input',
- type='hidden',
- name=targetName,
- id=targetName,
- value=self.targetValue,
- extra=self.extra)
- viewInput = renderElement(u'input',
- type='hidden',
- name=viewName,
- id=viewName,
- value=self.viewValue,
- extra=self.extra)
- titleInput = renderElement(u'input',
- type='hidden',
- name=titleName,
- id=titleName,
- value=self.titleValue,
- extra=self.extra)
- descriptionInput = renderElement(u'input',
- type='hidden',
- name=descriptionName,
- id=descriptionName,
- value=self.descriptionValue,
- extra=self.extra)
+ type='hidden',
+ name=targetName,
+ id=targetName,
+ value=self.targetValue,
+ extra=self.extra)
+ formDataInput = renderElement(u'input',
+ type='hidden',
+ name=formDataName,
+ id=formDataName,
+ value=self.formDataValue,
+ extra=self.extra)
linkTag = renderElement(self.refTag,
href = self.referenceEditorURL,
name=self.name,
@@ -164,7 +159,7 @@
contents=contents,
style=self.style,
extra=self.extra)
- return linkTag + viewInput + intidInput + titleInput + descriptionInput
+ return linkTag + intidInput + formDataInput
def _getFormValue(self):
res = super(ViewReferenceWidget,self)._getFormValue()
@@ -192,10 +187,8 @@
else:
ref = ViewReference()
# form field ids
+ formDataName = self.name + '.formData'
targetName = self.name + '.target'
- viewName = self.name + '.view'
- titleName = self.name + '.title'
- descriptionName = self.name + '.description'
# get target obj str
intid = self.request.get(targetName)
@@ -207,24 +200,21 @@
return self.context.missing_value
ref.target = obj
- # write view str
- viewStr = self.request.get(viewName)
- if viewStr is None:
- return self.context.missing_value
- ref.view = unicode(viewStr)
+ # apply the form data
+ formData = self.request.get(formDataName)
+ if not formData:
+ return ref
+ data = cgi.parse_qs(formData)
+ for k, v in data.items():
+ if type(v) is type([]) and len(v)==1:
+ data[k] = v[0]
- # write title str
- titleStr = self.request.get(titleName)
- if titleStr is None:
- return self.context.missing_value
- ref.title = unicode(titleStr)
-
- # write description str
- descriptionStr = self.request.get(descriptionName)
- if descriptionStr is None:
- return self.context.missing_value
- ref.description = unicode(descriptionStr)
-
+ # XXX this is a contract for edit form
+ data['form.actions.apply'] = u''
+ r = TestRequest(form=data)
+ klass = getEditorView(ref.target, self.request,
+ self.context.settingName).__class__
+ klass(ref, r).update()
return ref
Modified: z3c.reference/branches/flash/src/z3c/reference/interfaces.py
===================================================================
--- z3c.reference/branches/flash/src/z3c/reference/interfaces.py 2007-09-07 12:15:50 UTC (rev 79520)
+++ z3c.reference/branches/flash/src/z3c/reference/interfaces.py 2007-09-07 12:20:29 UTC (rev 79521)
@@ -28,16 +28,6 @@
view. If the target is None, the view name is supposed to be an
absolute url to an external target"""
- title = zope.schema.Text(
- title = u'Title',
- description = u'The title of the reference',
- )
-
- description = zope.schema.Text(
- title = u'Description',
- description = u'The description of the reference',
- )
-
target = zope.schema.Object(
schema=ILocation,
title=u'Target Object',
More information about the Checkins
mailing list