简体   繁体   中英

Can I use z3c.form on Plone portlets instead of zope.formlib?

What modifications do I need to make considering I have a vanilla ZopeSkel plone3_portlet formlib generated package? Ie:

  • From which classes should I inherit?
  • Which hooks must I provide?

Can I use it all the way down including five.grok and plone.directives.form?

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 ''

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

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.

If like me you've found this question 2 years later, then it might be handy to know that:

  1. ggozad's solution has been integrated into plone.app.portlets

  2. You still need to write the portlet on top of his solution (which I found hard to work out)

  3. I've put together a variation of my working code here

  4. 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)

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.

I believe that David Glick has accomplished this with Carousel . His documentation points to a known-good set that's worked for me.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM