[Grok-dev] Re: Cancel button in forms

Brandon Craig Rhodes brandon at rhodesmill.org
Mon May 5 16:37:30 EDT 2008

Martijn Faassen <faassen at startifact.com> writes:

> You need to explain how this will actually help the writer and the
> reader of code that deals with redirects significantly enough to be
> worth having another way of doing things.

Maybe I made the mistake of thinking everyone's Grok code looks like
mine. :-) Glancing over my Grok applications, there is only one place
where self.redirect() doesn't have self.url() inside of it, which is
when I'm directing someone off-site.  So this would very much help me,
at least, Not Repeat Myself. :-)

And I'm not sure what you mean by a different way of doing things.
Since a redirect, by its very definition, goes to a URL, it seems
obvious that whatever you pass to self.redirect(), whether string or
object or method, is going to be used by redirect() in some sort of
attempt to create a URL.  So you're doing what you always do: passing
to redirect() "the place you want to go" with the redirect.  You're
just getting the flexibility of passing any object that can be adapted
to a URL, rather than having to do the adaptation/conversion yourself.
(Which you always have the option of doing, of course, if Grok's
native way of figuring out an object's URL doesn't satisfy you.)

The constant and incessant need to call self.url() every time one
calls self.redirect() is exactly, in my PyCon talk on Zope, the
symptom that I indicated should signal a programmer for their need to
think about a component framework.  When you repeat self.url() every
time you call self.redirect(), you are spewing all over your code,
again and again, copies of a single piece of knowledge: your knowledge
of what redirect() needs.  By putting:

        destination = IAbsoluteURL(destination, destination)

at the top of redirect(), all of those dozens of self.url() calls all
through your code disappear, because the knowledge that they
represented and repeated over and over again then lives in once place.
It's an additional win that the "one place" that the knowledge lives
is right at the top of the redirect() function itself, where it can be
read along with the rest of the function. :-)

> You could do self.redirect(obj)' in some cases if self.redirect
> tried to adapt to IAbsoluteURL, but only if you're not redirecting
> to a view on that object or don't want to pass in URL paramters.

Are you claiming that a View cannot be adapted to IAbsoluteURL, or are
you pointing out that the resulting URL is really, really ugly and not
one that should ever, under any circumstances, be displayed to the
user? :-)

Why would URL parameters be forbidden?  Couldn't they still be encoded
in the dictionary passed as the second argument?  I don't see any
reason for disallowing this...

> Code that produces URLs might also become a bit harder to recognize;
> we'll have more than one ways to do things.

The code that produces URLs would stay exactly where it is: in a bunch
of adapters in zope.traversal.browser.absolute_url, where it's always
lived. :-) And having that magic kick off when someone writes
"self.redirect(some_object)" will be just about as opaque to the
end-programmer as having it kick off when he writes, more laboriously,
"self.redirect(self.url(some_object))". :-)

Brandon Craig Rhodes   brandon at rhodesmill.org   http://rhodesmill.org/brandon

More information about the Grok-dev mailing list