Reputation: 779
What modifications do I need to make considering I have a vanilla ZopeSkel plone3_portlet formlib generated package? Ie:
Can I use it all the way down including five.grok and plone.directives.form?
Upvotes: 5
Views: 1349
Reputation: 1228
If like me you've found this question 2 years later, then it might be handy to know that:
ggozad's solution has been integrated into plone.app.portlets
You still need to write the portlet on top of his solution (which I found hard to work out)
I've put together a variation of my working code here
Unless you are using Plone 5 you will need to keep plone.app.portlets < 3.0
A lot of credit to the author of this package (note that this was written BEFORE ggozad's solution was integrated into plone.app.portlets)
Upvotes: 2
Reputation: 13105
Yes, you can do that, what you need is the Add/Edit forms... Here's what I did it for a Jarn project, you can use AddForm and EditForm the same way you would use their formlib equvalent:
from Acquisition import aq_parent, aq_inner
from plone.app.portlets import PloneMessageFactory as _
from plone.app.portlets.browser.interfaces import IPortletAddForm
from plone.app.portlets.browser.interfaces import IPortletEditForm
from plone.app.portlets.interfaces import IPortletPermissionChecker
from z3c.form import button
from z3c.form import form
from zope.component import getMultiAdapter
from zope.interface import implements
class AddForm(form.AddForm):
implements(IPortletAddForm)
label = _(u"Configure portlet")
def add(self, object):
ob = self.context.add(object)
self._finishedAdd = True
return ob
def __call__(self):
IPortletPermissionChecker(aq_parent(aq_inner(self.context)))()
return super(AddForm, self).__call__()
def nextURL(self):
addview = aq_parent(aq_inner(self.context))
context = aq_parent(aq_inner(addview))
url = str(getMultiAdapter((context, self.request),
name=u"absolute_url"))
return url + '/@@manage-portlets'
@button.buttonAndHandler(_(u"label_save", default=u"Save"), name='add')
def handleAdd(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
obj = self.createAndAdd(data)
if obj is not None:
# mark only as finished if we get the new object
self._finishedAdd = True
@button.buttonAndHandler(_(u"label_cancel", default=u"Cancel"),
name='cancel_add')
def handleCancel(self, action):
nextURL = self.nextURL()
if nextURL:
self.request.response.redirect(nextURL)
return ''
class EditForm(form.EditForm):
"""An edit form for portlets.
"""
implements(IPortletEditForm)
label = _(u"Modify portlet")
def __call__(self):
IPortletPermissionChecker(aq_parent(aq_inner(self.context)))()
return super(EditForm, self).__call__()
def nextURL(self):
editview = aq_parent(aq_inner(self.context))
context = aq_parent(aq_inner(editview))
url = str(getMultiAdapter((context, self.request),
name=u"absolute_url"))
return url + '/@@manage-portlets'
@button.buttonAndHandler(_(u"label_save", default=u"Save"), name='apply')
def handleSave(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
changes = self.applyChanges(data)
if changes:
self.status = "Changes saved"
else:
self.status = "No changes"
nextURL = self.nextURL()
if nextURL:
self.request.response.redirect(self.nextURL())
return ''
@button.buttonAndHandler(_(u"label_cancel", default=u"Cancel"),
name='cancel_add')
def handleCancel(self, action):
nextURL = self.nextURL()
if nextURL:
self.request.response.redirect(nextURL)
return ''
Upvotes: 7
Reputation: 1274
The open source collective.dancing.browser.portlets.channelsubscribe moudle has implementations of portlets written in z3c.form.
It's a huge mess though. I'd recommend against doing anything fancy with Plone portlets because of its complexity will blow up in your face big time.
See http://dev.plone.org/collective/browser/collective.dancing/trunk/collective/dancing/browser/portlets/channelsubscribe.py or http://pypi.python.org/pypi/collective.dancing
Upvotes: 3
Reputation: 1125078
This certainly can be done. We already use this in a 4.0 Plone project, where a colleague created a base IPortletAddForm
and IPortletEditForm
implementations using z3c.form.form.AddForm
and z3c.form.form.EditForm
base classes respectively.
Note that this is Plone 4.0, not 3.x, so your mileage may vary.
The implementation is a basic reimplementation of their zope.formlib originals, with simple buttonAndHandler handlers to handle the Add (add form), Save (edit form) and Cancel (both) buttons.
I believe we have plans to contribute the base form implementations back to plone.app.portlets, I'll ask him about it.
Upvotes: 2
Reputation: 2579
I know this is an incomplete answer, but I believe it will point you in the right direction. The plonezohointegration product uses z3cforms for its portlets you can look at how the did it.
There's documentation on how it is done in the plone community developer documentation
Upvotes: 1
Reputation: 6048
I believe that David Glick has accomplished this with Carousel. His documentation points to a known-good set that's worked for me.
Upvotes: 1
Reputation: 3548
I think it's theoretically possible, yes, but I'm not sure anyone's tried it. It's probably something we'll need to do in Plone at one point, so it'd be great if you managed to make it work.
I'd start by looking at what the existing portlet form base classes do and try to emulate that in z3c.form. I'd also probably start without plone.directives.form and plone.autoform for now, as that will probably confuse you a bit to start with. Better to add those later.
The main thing, I suspect, will be to register a new default template for the new forms, and then add some hooks for the actual "add" and "edit" operations as per plone.app.portlets's base forms.
Upvotes: 1