[Grok-dev] Traverser, Request and URL mess
Martijn Faassen
faassen at startifact.com
Sat Oct 10 09:37:33 EDT 2009
Hey Souheil,
Souheil CHELFOUH wrote:
> I'm currently working on grokui.base and grokui.admin
> With Uli, we decided to use a namespace for the views, to get a cleaner base.
Thanks very much for doing this work!
> Everything is working nicely. The views are registered for a skin
> layer, the skin is applied on traversal by a namespace traverser,
> ++grokui++.
> However, when an application is created, we'd like to be
> able to acces its URL without having the traverser ++grokui++ added in
> the request. I couldn't find an easy way to do that without
> duplicating the request and modifying the _app_names.
We're talking about the ability to generate a URL to something in
another skin, correct? I.e. to generate a link to the application's URL,
and the application is *not* in the admin UI skin of course. The other
situation where this happens would be if you would want the root of the
site to redirect to the admin UI (which is in the ++grokui++ skin). But
we have the added complexity that ++grokui++ is its own namespace here,
instead of ++skin++grokui.
> I found 2
> solutions for that :
>
> # This is totaly ugly, but it works without much effort :)
> url = absoluteURL(application, request).replace('/++grokui++', '')
I think this is safe enough. It's ugly, but it has the virtue of being
short.
> # This is nicer, but maybe there's another solution :
> class GrokUINamespace(grok.MultiAdapter):
> grok.name('grokui')
> grok.provides(ITraversable)
> grok.adapts(IRootFolder, browser.IBrowserRequest)
>
> def __init__(self, context, request):
> self.context = context
>
> annotations = IAnnotations(request)
> grokui_info = annotations.get('grokui', None)
> if grokui_info is None:
> grokui_info = annotations['grokui'] = {}
> # we get the root url before the ++grokui++ is shifted
> # and use this URL to compute the application one
> grokui_info['root_url'] = request.getApplicationURL()
>
> applySkin(self.request, GrokUISkin)
> request.shiftNameToApplication()
>
> def traverse(self, name, ignore):
> return self.context
> Anyone could help me, with any kind of trick/tip/opinion ?
> The second solution works and is much nicer than the first one, but it
> looks a bit hackish.
Could you explain to me why you think the second solution is nicer? I
have a hard time even understand what could possibly be going on...
I don't think this is nicer, as it's totally complicated and it's hard
for me to understand what is going on. :) What *is* this doing?
If the problem indeed is about the ability to generate URLs to other
skins, this is a long-standing discussion with no conclusion. The story
appears to me that:
* we keep running into it
* it appears hard to devise a general solution
Since we keep runnign into it, perhaps we can come up with a more
limited solution, where it's at least possible to create URLs *without*
any ++skin++ bit in it, or to at least add ++skin++foo easily to an
existing URL (somewhere in the beginning). That won't cover all cases
(virtual hosts, namespaces not appearing at the root of the URL, other
things?) but it would cover a lot of them. We also need to make sure we
can handle your case, where instead of ++skin++foo, you just want ++foo++.
Perhaps we need an API like this:
self.url(..., namespace=('skin', 'foo')
to go to ++skin++foo
and:
self.url(..., namespace=('grokui',None)
to go to ++grokui++
and:
self.url(..., namespace=(None, None))
to have no special namespace.
the default would have namespace be None and it'd always generate URLs
within the same namespace then. This is what it does already.
I think it would probably simplest to make this work by simple but
well-tested string rewriting.
Regards,
Martijn
More information about the Grok-dev
mailing list