urls = (
'/', 'h_main_redirect',
'/wiki:register', 'h_register',
'/wiki:account', 'h_account',
'/wiki:login', 'h_login',
'/wiki:logout', 'h_logout',
'/wiki:recent-changes', 'h_recent_changes',
'/wiki:login', 'h_login',
'/wiki:logout', 'h_logout',
'/([^/]+)', 'h_page',
'/([^/]+)/history', 'h_history',
)
To make it less likely that there'll be mistakes, inconsistencies,
etc. and to save a little bit of typing, we could use this feature to
change it to something like this:
urls = (
'/', 'h_main_redirect',
'/wiki:', [
'register', 'h_register',
'account', 'h_account',
'login', 'h_login',
'logout', 'h_logout',
'recent-changes', 'h_recent_changes',
'login', 'h_login',
'logout', 'h_logout',
],
'/([^/]+)', [
'', 'h_page',
'/history', 'h_history',
],
)
This would be flattened into a tuple identical to the one given above.
Of course, it could be any number of levels deep.
> As your URLs tuple (for web.request.handle) gets longer, it seems to
> me that it would be useful to be able to specify things
> hierarchically instead of completely as flat regexes.
Right on... one thing I would find useful would be to express an object
method call as a URL...
For example, one could construct a URL along these lines:
/[object]/[instance]/[method].[argument]/
E.g.:
/date/1999/12/31/editor/configuration.1
'/date' being the object
'/1999/12/31' the instance
'/editor' a method
'/configuration.1' another method with one argument
For illustration purpose, here is an implementation in Lua with does
this [1][2]:
-- first. one construct a so-called service
-- the first parameter is the object prefix, the root of a path
hierarchy
-- the second parameter is an object class, e.g. 'Date'
-- the third and fourth parameters are functions to translate an object
to a URL and vis-versa
local aService = HTTPService( '/date/', Date, toURL, toObject )
-- then, one registers the service with the HTTP engine
-- note that you only need to register the root of the path hierarchy
HTTP[ aService.pattern ] = aService()
Upon invocation, the service calls toObject to translate a URL to an
object instance (e.g. '/1999/12/31' -> aDate). Then it translates the
remaining of the path into a method invocation chain (e.g. GET
'/editor' -> getEditor() or POST '/editor' -> postEditor() ). Each
method invocation can have some optional, dot separated, arguments
(e.g. PUT '/configuration.1' -> putConfiguration( 1 ) ).
Anyway, just a thought :)
Cheers,
PA.
[1] http://dev.alt.textdrive.com/browser/HTTP/HTTP.lua#L435
[2] http://dev.alt.textdrive.com/browser/HTTP/HTTPExtra.lua#L432
(
'wiki:(.*)', 'handler.\1'
)
go pretty far along?
Well, not if you only want to match a few words and not every possible
resource starting with "wiki:". In that case you would have to use something
like "wiki:((?:foo)|(?:bar))$", assuming your handlers even have the same
names in the first place (not possible when you want to use non-alphanumerical
characters and the like).
Anyway, in reply to Adam: I am not sure if this will actually make it look
cleaner. Also, I doubt adding nested lists automatically makes it "less error
prone". I am not sure if this is worth it—I like how webpy is small and only
has the absolutely necessary features. Then again, maybe that is just me.
Maybe you could provide (and maintain) a patch for people who are interested?
I am undecided.
b^4
urls = (
'/admin.*', 'admin.controller.parse',
'/ajax.*' , 'ajax.controller.parse',
)
Now, within each 'controller.parse' I parse the path again and act
accordingly.
With this approach I gain a clean, small-sliced and readable code ---
as I love.
This is an example for ajax.controller.parse (which has a switch-like
technique as well):
class parse:
def GET(self):
json_res = ""
self.url = web.ctx.path
params = web.input()
switch = {
".*/ajax/sync": self.sync,
".*/ajax/helloworld" : self.helloworld,
".*/ajax/vext/add" : self.users_add_vext,
".*/ajax/vext/delete" : self.users_delete_vext,
".*/ajax/ddi/add" : self.users_add_ddi,
".*/ajax/ddi/delete" : self.users_delete_ddi,
".*/ajax/groups/add/": self.groups_add,
".*/ajax/groups/del/": self.groups_del
}
for knownurl in switch:
if re.match(knownurl, self.url):
json_res = switch[knownurl](params)
break
web.header("Content-Type","X-JSON")
print json_res