[Product-Developers] Re: Traversing from a z3c.form action handler
optilude+lists at gmail.com
Mon Feb 15 06:09:23 UTC 2010
> It was 3 am when I got to this point, but yes, that was the first thing I
> tried. Response.redirect appears to lose the data I've set on the request
> in my form action.
Unless you pass it along (e.g. in a query string), that'll happen. A
redirect just sends a 301 response to the browser telling it to load a
You could construct a URL with a query string, though. That's probably
the first thing I'd try.
> I remember reading a blog post at one point about using
> a traversal technique instead of response.redirect to keep the original
> request and all its data intact as you move from one page to another. It
> seems that ControllerPageTemplates must use something like this, since all
> of their metadata contain references to 'TraverseTo'.
Yes, FormController works like this. All it's really doing is to look up
another object, calling it to get a string of raw HTML, and returning
that as the response body. So the browser (and hence the URL bar) has no
idea what's going on. This is kind of like invoking an alternative page
It's a bit confusing, though. It may work because you set something in
the request and the same request object is used when you "traverse" to
the other view/template/object. There's the potential for things to leak
across the two views, though.
> I'm not terrifically concerned about the URL being wrong, but I've not
> managed to have returning the URL do anything.
> Here's what I have in the action so far:
> class AnimalTable(HydraCrudEditForm):
> label = _(u'My Animals')
> @button.buttonAndHandler(u'Change State', name='state_change')
> def handle_state_change(self, action):
> """ traverse to the content_status_share form for processing
> true_context = self.context.context
> selected = self.selected_items()
> paths = 
> if selected:
> paths = [item.absolute_url_path() for id, item in selected]
> self.request.form['paths'] = paths
> path = true_context.absolute_url_path() +
> state_view = true_context.restrictedTraverse(path)
> return state_view()
> IStatusMessage(self.request).add("No animals selected",
> Unfortunately, that just ends up by reloading the original form without any
> indication that anything has happened.
I think you'd need to override render() to conditionally return the
state_view() stuff, and conditionally use the standard template (or call
the base class version). render() is called after the action handler.
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book
More information about the Product-Developers