I'm still digesting this, but this type of system is the end goal,
assuming it can be made to work.
The things to look out for are that it doesn't interfere with Context
determination, and that it doesn't interfere with the feature that
permits dropping the filename extension from the URL, ie:
http://localhost/Welcom goes to Welcome.py. With your "static" tree
setup, I don't think that would be a problem. But, this would have to
work dynamically too, like the current system.
As far as moving serverSidePathForRequest to the Context object, that is
something I would like to do, but there is no Context object to move it
to at the moment. This is a point of internal discussion. We have been
talking about whether we should have contexts at all. The opinion has
been put forth that we should drop the contexts all together, and if you
need special functionality, you should build it into the application
class. If you need the effect of multiple contexts, you should run
multiple servers.
I think that makes things difficult, unnecssarily. Whether we provide
the context functionality or not, you can always run multiple servers if
you want to. I see no need to remove functionality. Let those who
don't want contexts just run multiple servers, and those who do want
them can still have them.
If we were to keep contexts, then we could create a Context class where
extraPathInfo could be turned on or off, or a new Servlet selection
routine could be plugged in individually for each context, etc. It
would simply be a matter of subclassing Context and overriding any
functions necessary.
This does, however, bring up one thing that we are missing, and that is
a standardized directory layout. By which I mean, it would make the
setup easier if all Contexts were designed like so:
ContextRoot
|
|
--ConfigurationDirectory
|
|
--CansDirectory
|
|
--ContentDirectory
I have been using a setup like this, and it works pretty well. It
wouldn't even have to be this structured; if we required each Context to
be a package, then the __init__.py could define standard variables, like
the config directory, and the Context class to use, etc.
Anyway, I've gone off topic, but I'm hoping I'll stir up some discussion.
In any case, you path determination code looks intriguing. Maybe it
doesn't have to be the default. Maybe you could optionally call that
code after the primary context had been determined?
Jay
Terrel Shumway wrote:
> extraURLPath is useful for URLs like /news/{year}/{month}/{day}
>
> What about URLs like these?
> /{client_company}/{order_number}/messages/{message_id}
> /{project}/patches/{patch_no}/raw
>
> Here is my solution, which I finished before I read about extraURLPath.
> --- path.py -----------
> import os
> import pathconfig
>
> def translate_path( pathinfo, tree=pathconfig.tree ):
> """translate a url to a path in the document tree
>
> e.g.
> pathinfo: /2312-2312-123-123/origin
> tree has: /{order}/origin
>
> => ( "/{order}/orgin", { "order": "2312-2312-123-123" } )
>
> Hmmm... This sounds a lot like mod_rewrite....
>
> """
> parts = filter( None, pathinfo.split( "/" ))
>
> vars = {}
>
> treepath = "/"
> for part in parts:
> static,dynamic = tree[ treepath ]
> if part in static:
> treepath = os.path.join( treepath, part )
> else:
> for d in dynamic:
> m = d[0](part)
> if m:
> treepath = os.path.join( treepath, d[1] )
> v = m.groupdict()
> for k in v.keys():
> vars[k] = v[k]
> break
> return treepath, vars
> ---------------------------------------
> --- pathconfig.py ---------------
> import re
>
> tree = {
> #folder, static, dynamic
> "/": (
> ( "login", "support", "reports", "register", "admin",
> "profile", "new-order", "current-orders", "closed-orders",
> "archive",
> ),
> ( ( re.compile("(?P<order>.*)").match, "{order}" ), )
> ),
> "/{order}" : (
> ( "origin", "destination", "messages", "contacts",
> "change-order" ),
> ( ( re.compile("(?P<service>.*)").match, "{service}" ), )
> ),
> "/{order}/{service}" : (
> ( ),
> ( ( re.compile("(?P<task>.*)").match, "{task}" ), )
> ),
> "/{order}/{service}/{task}" : (
> ( "edit", "upload-doc", ),
> (
> ( re.compile("doc-(?P<doc_id>.*)").match, "doc-{doc_id}" ),
> ( re.compile("(?P<item>.*)").match, "{item}" ),
> )
> ),
> "/{order}/messages" : (
> ( "compose", ),
> ( ( re.compile("(?P<message_id>.*)").match, "{message_id}" ), )
> ),
> "/profile" : (
> ( ),
> ( ( re.compile("(?P<user_id>.*)").match, "{user_id}" ), )
> ),
> "/profile/{user_id}" : (
> ( "edit", ),
> ( )
> ),
> }
>
> del re
> ---------------------------------------
> This works very well for my purposes.
> Some features:
> * Specifying the tree completely and explicitly, rather than reading
> from the filesystem,
> while it adds a slight maintenance burden, also dramatically
> increases security because no reference
> to the filesystem is ever typed directly by the user. (no
> "/foo/bar/.htaccess"-like problems)
> * I can intersperse "dynamic" and "static" pieces of the URL in any
> way that makes sense for
> my application: extraPathInfo can be anywhere, and WebKit can still
> resolve the url to a specific folder/script
> * This does not suffer from the BASE problem, as far as I can tell.
> (I may be wrong.)
>
> Caveat:
> If there is more than one dynamic component at any level, order
> matters.
> (See "/{order}/{service}/{task}" above.)
>
>
> My questions:
> *Other than performing careful regression testing (which should be
> automated), what should I watch out for
> in modifying Application.serverSidePathForRequest()?
> * Is anyone else doing something similar?
> * Does anyone have suggestions for
> improving/modularizing/generalizing this solution?
> * Should WebKit add hooks for arbitrary path manipulation code?
> (e.g. move serverSidePathForRequest into Context,
> or provide a list of functions to do this a la
> ChainOfResponsibility pattern) (When I was following the Zope
> discussion
> some time back, several people came up with different
> (incompatible) solutions to this problem in support of virtual hosting.
> It seems to be a common need.)
>
>
> _______________________________________________
> Webware-discuss mailing list
> Webware-discuss@...
> http://lists.sourceforge.net/mailman/listinfo/webware-discuss
|