> Can you give an example of circumstances where the index would be
> useful? I can't imagine one on my own.
Sorry for the length.
I am working on an app that has a user authentication part. I need the
following paths:
/config/
returns a page with all the configuration commands
/config/users
returns a page with the list of all the known users
/config/user/add
returns a form with empty fields for a new user
/config/user/[loginName]/modify
returns a form with current values for a known user
/config/user/validate
used as a form action, validates values for a added or modified user
/config/user/[loginName]/delete
deletes a known user
I have a ConfigUI object that iterates over the component, answers directly
in the first two cases, and creates and returns UserForm(Form) objects when
the second level component is "user".
Currently it is all implemented in its _q_getname method, by means of a
case-like switch shaped like this:
if self.nextCompLevel == 2:
# level 2 URL component: /config/something
if component not in self.knownURLClasses.keys():
message = "Unknown level 2 URL component: %s" % component
raise TraversalError, message
else:
# /config/user , store the component
self.currObjKind = component
# advance state to next level
self.nextCompLevel = 3
# get next component
return self
elif self.nextCompLevel == 3:
# level 3 URL component: /config/user/something
# could be 'add', 'validate', or a login name
if component == 'add':
# /config/user/add, create a new form object
# and lose the old one, if already there
self.forms[self.currObjKind] = \
self.knownURLClasses[self.currObjKind](self.app)
# URL ended, reset state for next call
self.nextCompLevel = 2
# call the appropriate object 'add' method
return self.forms[self.currObjKind].add(request)
elif component == 'validate':
# /config/user/validate, need an existing form object
if not self.forms.get(self.currObjKind):
message = "Validate without existing %s form, object %s" \
% (self.currObjKind, self.currObjItem)
raise TraversalError, message
# check passed, URL ended, reset state for next call
self.nextCompLevel = 2
# call the appropriate object 'validate' method
return self.forms[self.currObjKind].validate(request)
else:
# it's a login name, store it
self.currObjItem = component
# advance state to next level
self.nextCompLevel = 4
return self
elif self.nextCompLevel == 4:
# level 4 URL component: /config/user/login/something
if component in ('delete', 'modify'):
# create a new form object and lose the
# old one, if already there
self.forms[self.currObjKind] = \
self.knownURLClasses[self.currObjKind](self.app)
# pass the recorded item to the form object
self.forms[self.currObjKind].setState(self.currObjItem)
# URL ended, reset state for next call
self.nextCompLevel = 2
# call the appropriate object method
if component == 'delete':
return self.forms[self.currObjKind].delete(request)
else:
return self.forms[self.currObjKind].modify(request)
else:
message = "Unknown form action, component: %s" % component
raise TraversalError, message
else:
message = "Unknown next component level: %s" % self.nextCompLevel
raise TraversalError, message
The __init__ contains this:
self.nextCompLevel = 2
self.currObjKind = ''
self.currObjItem = ''
self.forms = {}
Having the index passed to the _q_getname would allow me not to keep track
of what the next component level should be, and choose a path of action
based on what it really is.
P.S.: of course most "else"s are superfluous, but I keep them for clarity.
And obviously the "validate" method refuses "add" and "validate" as login
names. Not the cleanest way, I know. :^) But the alternative is to have
something like
/config/user/dummy/add
or, worse, query strings. :^)
--
"Python is the Beatles of programming languages."
Aaron K. Johnson on comp.lang.python
Nicola Larosa - nico@tekNico.net